├── .DS_Store ├── 1-250 ├── .DS_Store ├── 134._Gas_Station.md ├── 165._compare_version_numbers.md ├── 166._Fraction_to_Recurring_Decimal.md ├── 209._Minimum_Size_Subarray_Sum.md ├── 211. Add and Search Word - Data structure design.md └── 213._house_robber_ii.md ├── 251-500 ├── 263._ugly_number.md ├── 264._ugly_number_ii.md ├── 265. Paint House II.md ├── 266. Palindrome Permutation.md ├── 267. Palindrome Permutation II.md ├── 268._missing_number.md ├── 269._Alien_Dictionary.md ├── 270._Closest_Binary_Search_Tree_Value.md ├── 276. Paint Fence.md ├── 277. Find the Celebrity.md ├── 278._First_Bad _Version.md ├── 279._perfect_squares.md ├── 280._Wiggle_Sort.md ├── 283._move_zeroes.md ├── 285._inorder_successor_in_bst.md ├── 286. Walls and Gates.md ├── 287._Find_the_Duplicate_Number.md ├── 289._game_of_life.md ├── 290._word_pattern.md ├── 292._nim_game.md ├── 293._Flip_Game.md ├── 296. Best Meeting Point.md ├── 298. Binary Tree Longest Consecutive Sequence.md ├── 299._bulls_and_cows.md ├── 300._longest_increasing_subsequence.md ├── 303._range_sum_query_-_immutable.md ├── 305._Number_of_Islands_II.md ├── 311._Sparse_Matrix_Multiplication.md ├── 316._Remove_Duplicate_Letters.md ├── 319._Bulb_Switcher.md ├── 322._Coin_Change.md ├── 323._number_of_connected_components_in_an_undirected_graph.md ├── 324._Wiggle_Sort_II.md ├── 325._Maximum_Size_Subarray_Sum_Equals_k.md ├── 326._power_of_three.md ├── 334._increasing_triplet_subsequence.md ├── 336._Palindrome_Pairs.md ├── 337._house_robber_iii.md ├── 338._Counting_Bits.md ├── 339. Nested List Weight Sum.md ├── 340._Longest_Substring_with_At_Most_K_Distinct_Characters.md ├── 342._Power_of_Four.md ├── 344._reverse_string.md ├── 345._Reverse_Vowels_of_a_String.md ├── 347._Top_K_Frequent_Elements.md ├── 349._intersection_of_two_arrays.md ├── 350._intersection_of_two_arrays_ii.md ├── 353. Design Snake Game.md ├── 361._Bomb_Enemy.md ├── 364. Nested List Weight Sum II.md ├── 367._valid_perfect_square.md ├── 371._sum_of_two_integers.md ├── 374._Guess_Number_Higher_or_Lower.md ├── 377._combination_sum_iv.md ├── 378._kth_smallest_element_in_a_sorted_matrix.md ├── 380._Insert_Delete_GetRandom_O(1).md ├── 381._Insert_Delete_GetRandom_O(1)_-_Duplicates_allowed.md ├── 382._linked_list_random_node.md ├── 383._ransom_note.md ├── 384. Shuffle an Array.md ├── 386._Lexicographical_Numbers.md ├── 387._first_unique_character_in_a_string.md ├── 388._Longest_Absolute_File_Path.md ├── 389._find_the_difference.md ├── 392._is_subsequence.md ├── 394._decode_string.md ├── 400._Nth_Digit.md ├── 401._binary_watch.md ├── 402._Remove_K_Digits.md ├── 403._Frog_Jump.md ├── 405. Convert a Number to Hexadecimal.md ├── 406._Queue_Reconstruction_by_Height.md ├── 412._fizz_buzz.md ├── 413. Arithmetic Slices.md ├── 414._third_maximum_number.md ├── 415._add_strings.md ├── 416._Partition_Equal_Subset_Sum.md ├── 421._Maximum_XOR_of_Two_Numbers_in_an_Array.md ├── 422. Valid Word Square.md ├── 424._Longest_Repeating_Character_Replacement.md ├── 434._number_of_segments_in_a_string.md ├── 435._Non-overlapping_Intervals.md ├── 436._Find_Right_Interval.md ├── 439. Ternary Expression Parser.md ├── 441._arranging_coins.md ├── 442._Find_All_Duplicates_in_an_Array.md ├── 448._Find_All_Numbers_Disappeared_in_an_Array.md ├── 453._Minimum_Moves_to_Equal_Array_Elements.md ├── 457._Circular_Array_Loop.md ├── 459._Repeated_Substring_Pattern.md ├── 461._Hamming Distance.md ├── 463._Island_Perimeter.md ├── 467._Unique_Substrings_in_Wraparound_String.md ├── 469. Convex Polygon.md ├── 476._Number_Complement.md ├── 477._Total_Hamming_Distance.md ├── 485._Max_Consecutive_Ones.md ├── 494._Target_Sum.md └── 496._Next_Greater_Element_I.md ├── 501-750 ├── 507._Perfect_Number.md ├── 536._Construct_Binary_Tree_from_String.md ├── 539._Minimum_Time_Difference.md ├── 547._Friend_Circles.md ├── 560._Subarray_Sum_Equals_K.md ├── 564._Find_the_Closest_Palindrome.md ├── 581._Shortest_Unsorted_Continuous_Subarray.md ├── 587._Erect_the_Fence .md ├── 592._Fraction_Addition_and_Subtraction.md ├── 593._Valid_Square.md ├── 595._Big_Countries.md ├── 599._Minimum_Index_Sum_of_Two_Lists.md ├── 606._Construct_String_from_Binary_Tree.md ├── 611._Valid_Triangle_Number.md ├── 613._Shortest_Distance_in_a_Line.md ├── 630._Course_Schedule_III.md ├── 646._Maximum_Length_of_Pair_Chain.md ├── 647._Palindromic_Substrings.md ├── 653._Two_Sum_IV_-_Input_is_a_BST.md ├── 657._Judge_Route_Circle.md ├── 665._Non-decreasing_Array.md ├── 672._Bulb_Switcher_II.md ├── 678._Valid_Parenthesis_String.md ├── 680._Valid_Palindrome_II.md ├── 681._Next_Closest_Time.md ├── 682._Baseball_Game.md ├── 685._Redundant_Connection_II.md ├── 687._Longest_Univalue_Path.md ├── 693._Binary_Number_with_Alternating_Bits.md ├── 695._Max_Area_of_Island.md ├── 698._Partition_to_K_Equal_Sum_Subsets.md ├── 707._Design_Linked_List.md ├── 713._Subarray_Product_Less_Than_K.md ├── 724._Find_Pivot_Index.md ├── 733._Flood_Fill.md ├── 739._Daily_Temperatures.md └── 740._delete_and_earn.md ├── 751-920 ├── 760._Find_Anagram_Mappings.md ├── 763._Partition_Labels.md ├── 766._Toeplitz_Matrix.md ├── 774._Minimize_Max_Distance_to_Gas_Station.md ├── 777. Swap_Adjacent_in_LR_String.md ├── 785._Is_Graph_Bipartite?.md ├── 792._Number_of_Matching_Subsequences.md ├── 796._Rotate_String.md ├── 800._Similar_RGB_Color.md ├── 801._Minimum_Swaps_To_Make_Sequences_Increasing.md ├── 815._Bus_Routes.md ├── 824._Goat_Latin.md ├── 844._Backspace_String_Compare.md ├── 865._Smallest_Subtree_with_all_the_Deepest_Nodes.md ├── 871._Minimum_Number_of_Refueling_Stops.md ├── 873._Length_of_Longest_Fibonacci_Subsequence.md ├── 878._Nth_Magical_Number.md ├── 890._Find_and_Replace_Pattern.md ├── 891._Sum_of_Subsequence_Widths.md ├── 900._RLE_Iterator.md ├── 902._Numbers_At_Most_N_Given_Digit_Set.md ├── 904._Fruit_Into_Baskets.md ├── 905._Sort_Array_By_Parity.md ├── 907._Sum_of_Subarray_Minimums.md ├── 908._Smallest_Range.md ├── 910._Smallest_Range_II.md ├── 914._X_of_a_Kind_in_a_Deck_of_Cards.md ├── 915._Partition_Array_into_Disjoint_Intervals.md ├── 916._Word_Subsets.md ├── 917._Reverse_Only_Letters.md ├── 918._Maximum_Sum_Circular_Subarray.md ├── 919._Complete_Binary_Tree_Inserter.md └── 920._Number_of_Music_Playlists.md ├── Backtracking.md ├── Backtracking ├── .DS_Store └── read │ ├── 017._letter_combinations_of_a_phone_number.md │ ├── 022._generate_parentheses.md │ ├── 031._next_permutation.md │ ├── 039._combination_sum.md │ ├── 040._combination_sum_ii.md │ ├── 046._permutations.md │ ├── 047._permutations_ii.md │ ├── 051._n-queens.md │ ├── 052._n-queens_ii.md │ ├── 060._permutation_sequence.md │ ├── 077._combinations.md │ ├── 078._Subsets.md │ ├── 079._word_search.md │ ├── 089._gray_code.md │ ├── 090._subsets_ii.md │ ├── 126. Word Ladder II.md │ ├── 127._word_ladder.md │ ├── 130._surrounded_regions.md │ ├── 200._number_of_islands.md │ ├── 207._course_schedule.md │ ├── 210._course_schedule_ii.md │ └── 216._combination_sum_iii.md ├── Behaviorial-Questions.md ├── Binary-search.md ├── Binary-search ├── .DS_Store ├── 034._Search for a Range.md ├── 035._search_insert_position.md ├── 069._sqrt(x).md ├── 074._search_a_2d_matrix.md ├── 240._search_a_2d_matrix_ii.md └── read │ ├── 033._search_in_rotated_sorted_array.md │ ├── 153._find_minimum_in_rotated_sorted_array.md │ ├── 154._Find_Minimum_in_Rotated_Sorted_Array_II.md │ └── 162._find_peak_element.md ├── Bit-manipulation.md ├── Bit-manipulation ├── .DS_Store └── read │ ├── 136._single_number.md │ ├── 137._Single_Number_II.md │ ├── 191._number_of_1_bits.md │ ├── 201._Bitwise_AND_of_Numbers_Range.md │ ├── 217._contains_duplicate.md │ ├── 219._contains_duplicate_ii.md │ └── 231. _Power_of_Two.md ├── DP.md ├── DP ├── .DS_Store ├── 014._longest_common_prefix.md ├── 032._longest_valid_parentheses.md ├── 218._The_Skyline_Problem.md └── read │ ├── 010._regular_expression_matching.md │ ├── 044._wildcard_matching.md │ ├── 053._maximum_subarray.md │ ├── 062._unique_paths.md │ ├── 063.unique_paths_ii.md │ ├── 064._minimum_path_sum.md │ ├── 070._Climbing_Stairs.md │ ├── 072._edit_distance.md │ ├── 084._Largest_Rectangle_in_Histogram.md │ ├── 085._Maximal_Rectangle.md │ ├── 091._decode_ways.md │ ├── 093._restore_ip_addresses.md │ ├── 118._pascal's_triangle.md │ ├── 119. _Pascal's_Triangle_II.md │ ├── 120. Triangle.md │ ├── 121._Best_Time_to_Buy_and_Sell_Stock.md │ ├── 122._Best_Time_to_Buy_and_Sell_Stock_II.md │ ├── 131._palindrome_partitioning.md │ ├── 139._word_break.md │ ├── 140._word_break_ii.md │ ├── 152._maximum_product_subarray.md │ ├── 174._dungeon_game.md │ └── 221._maximal_square.md ├── Divide-Conquer.md ├── Linked-list.md ├── Linked-list ├── .DS_Store ├── 146._LRU_Cache.md ├── 328._odd_even_linked_list.md ├── 341._Flatten_Nested_List_Iterator.md ├── 369.Plus One Linked List.md └── read │ ├── 002._add_two_numbers.md │ ├── 019._remove_nth_node_from_end_of_list.md │ ├── 021._merge_two_sorted_lists.md │ ├── 023._merge_k_sorted_lists.md │ ├── 024._swap_nodes_in_pairs.md │ ├── 061._rotate_list.md │ ├── 082._remove_duplicates_from_sorted_list_ii.md │ ├── 083._remove_duplicates_from_sorted_list.md │ ├── 086._partition_list.md │ ├── 092._reverse_linked_list_ii.md │ ├── 141._linked_list_cycle.md │ ├── 142_Linked_List_Cycle_II.md │ ├── 143._reorder_list.md │ ├── 147._insertion_sort_list.md │ ├── 148._sort_list.md │ ├── 160._intersection_of_two_linked_lists.md │ ├── 203._remove_linked_list_elements.md │ ├── 206._reverse_linked_list.md │ ├── 234._palindrome_linked_list.md │ └── 237._delete_node_in_a_linked_list.md ├── Matrix.md ├── Matrix ├── .DS_Store └── read │ ├── 048._rotate_image.md │ ├── 054._spiral_matrix.md │ ├── 059._spiral_matrix_ii.md │ └── 073. Set Matrix Zeroes.md ├── Misc.md ├── Misc ├── .DS_Store └── read │ ├── .DS_Store │ ├── 001._two_sum.md │ ├── 006._ZigZag_Conversion.md │ ├── 007._Reverse_Integer.md │ ├── 008._string_to_integer_(atoi).md │ ├── 009._Palindrome_Number.md │ ├── 012._Integer_to_Roman.md │ ├── 013._Roman_to_Integer.md │ ├── 027._Remove_Element.md │ ├── 038._Count_and_Say.md │ ├── 043._multiply_strings.md │ ├── 045._Jump_Game_II.md │ ├── 049._group_anagrams.md │ ├── 050._pow(x,_n).md │ ├── 055._jump_game.md │ ├── 056._Merge_Intervals.md │ ├── 057._Insert_Interval.md │ ├── 058._length_of_last_word.md │ ├── 066._plus_one.md │ ├── 067._add_binary.md │ ├── 088._merge_sorted_array.md │ ├── 133._clone_graph.md │ ├── 151._reverse_words_in_a_string.md │ ├── 168._excel_sheet_column_title.md │ ├── 169._majority_element.md │ ├── 171._excel_sheet_column_number.md │ ├── 172._Factorial_Trailing_Zeroes.md │ ├── 179._Largest_Number.md │ ├── 189._rotate_array.md │ ├── 198._house_robber.md │ ├── 204._count_primes.md │ ├── 205._isomorphic_strings.md │ ├── 223._rectangle_area.md │ ├── 228._summary_ranges.md │ ├── 229._majority_element_ii.md │ ├── 242._valid_anagram.md │ └── 258_ Add_Digits.md ├── Premium ├── 157._Read_N_Characters_Given_Read4.md ├── 158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md ├── 159._Longest_Substring_with_At_Most_Two_Distinct_Characters.md ├── 170._Two_Sum_III_-_Data_structure_design.md ├── 176._Second_Highest_Salary.md ├── 182._duplicate_emails.md ├── 249._Group_Shifted_Strings.md ├── 251._Flatten_2D_Vector.md ├── 252._Meeting_Rooms.md ├── 253._Meeting_Rooms_II.md ├── 254._Factor_Combinations.md ├── 255._Verify_Preorder_Sequence_in_Binary_Search_Tree.md └── 256. Paint House.md ├── Quick-select.md ├── Quick-select └── read │ ├── 004._median_of_two_sorted_arrays.md │ └── 215._Kth_Largest_Element_in_an_Array.md ├── README.md ├── Stack-Queue-Heap-Sort-Graph.md ├── Stack-Queue-Heap-Sort-Graph └── read │ ├── 020._valid_parentheses.md │ ├── 071._simplify_path.md │ ├── 150._evaluate_reverse_polish_notation.md │ ├── 155._min_stack.md │ ├── 224. Basic Calculator .md │ ├── 225._implement_stack_using_queues.md │ ├── 227._basic_calculator_ii.md │ └── 232._implement_queue_using_stacks.md ├── Summary ├── DFS和BFS.md ├── Data Structure and Algorthim Review.md ├── Introduction to String Searching Algorithms – topcoder.pdf ├── Maximal Square.pdf ├── Python刷题技巧笔记.md ├── Range Sum Query 2D - Immutable.pdf ├── backtracking思路.md ├── python_base.md ├── python的各种pass.md ├── read │ ├── Binary Search.md │ ├── Dynamic Programming.md │ ├── Java各种类型的转换.md │ ├── LinkedList技巧.md │ ├── Recusrion & BackTracking.md │ ├── delete_node_in_a_linked_list问题.md │ ├── slide_windows_template.md │ ├── 二叉树的一些操作.md │ ├── 斐波那契的DP思考.md │ ├── 递归_recursion.md │ └── 面试确认题目细节问题.md ├── union_find.md ├── 位运算.md ├── 全排列算法.md ├── 八排序.md ├── 子集合问题.md ├── 总结.md ├── 组合问题.md └── 编程思路总结.md ├── System-Design.md ├── Tree.md ├── Tree ├── .DS_Store ├── 114._flatten_binary_tree_to_linked_list.md ├── 222._count_complete_tree_nodes.md ├── 257._binary_tree_paths.md ├── 261. Graph Valid Tree.md ├── 366. Find Leaves of Binary Tree.md ├── 404._sum_of_left_leaves.md ├── 437._path_sum_iii.md └── read │ ├── 094._binary_tree_inorder_traversal.md │ ├── 096._unique_binary_search_trees.md │ ├── 098._validate_binary_search_tree.md │ ├── 100._same_tree.md │ ├── 101._symmetric_tree.md │ ├── 102._binary_tree_level_order_traversal.md │ ├── 103._binary_tree_zigzag_level_order_traversal.md │ ├── 104._maximum_depth_of_binary_tree.md │ ├── 105._construct_binary_tree_from_preorder_and_inorder_traversal.md │ ├── 106._construct_binary_tree_from_inorder_and_postorder_traversal.md │ ├── 107._binary_tree_level_order_traversal_ii.md │ ├── 108._convert_sorted_array_to_binary_search_tree.md │ ├── 109._convert_sorted_list_to_binary_search_tree.md │ ├── 110._balanced_binary_tree.md │ ├── 111._minimum_depth_of_binary_tree.md │ ├── 112._path_sum.md │ ├── 113._path_sum_ii.md │ ├── 116._populating_next_right_pointers_in_each_node.md │ ├── 117._Populating_Next_Right_Pointers_in_Each_Node_II.md │ ├── 124._Binary_Tree_Maximum_Path_Sum.md │ ├── 129._sum_root_to_leaf_numbers.md │ ├── 144._binary_tree_preorder_traversal.md │ ├── 145._binary_tree_postorder_traversal.md │ ├── 173._binary_search_tree_iterator.md │ ├── 199._binary_tree_right_side_view.md │ ├── 208._implement_trie_(prefix_tree).md │ ├── 226._invert_binary_tree.md │ ├── 230._kth_smallest_element_in_a_bst.md │ ├── 235._lowest_common_ancestor_of_a_binary_search_tree.md │ ├── 236._lowest_common_ancestor_of_a_binary_tree.md │ ├── 450. Delete Node in a BST.md │ └── 701._Insert_into_a_Binary_Search_Tree.md ├── Two-pointers.md ├── Two-pointers ├── .DS_Store ├── 030._Substring_with_Concatenation_of_All_Words.md ├── 076._Minimum_Window_Substring.md └── read │ ├── 003._longest_substring_without_repeating_characters.md │ ├── 005._longest_palindromic_substring.md │ ├── 011._container_with_most_water.md │ ├── 015._3sum.md │ ├── 016._3sum_closest.md │ ├── 018._4sum.md │ ├── 026._Remove_Duplicates_from_Sorted_Array.md │ ├── 028._implement_strstr().md │ ├── 041._First_Missing_Positive.md │ ├── 042._trapping_rain_water.md │ ├── 075._sort_colors.md │ ├── 125._valid_palindrome.md │ ├── 128._Longest_Consecutive_Sequence.md │ ├── 167._two_sum_ii_-_input_array_is_sorted.md │ ├── 238._product_of_array_except_self.md │ ├── 239._Sliding_Window_Maximum.md │ └── 438._Find_All_Anagrams_in_a_String.md ├── Uber.md ├── Uber1.md ├── amazon_onsite.md ├── google.md └── python.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/.DS_Store -------------------------------------------------------------------------------- /1-250/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/1-250/.DS_Store -------------------------------------------------------------------------------- /1-250/165._compare_version_numbers.md: -------------------------------------------------------------------------------- 1 | ###165. Compare Version Numbers 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 其实我并不觉得这个很简单 13 | 14 | 因为可能两个的位数不一样,首端或者尾端需要补0,同时我还考虑过可能有出现多个'.'的状况 15 | 16 | 17 | 18 | ``` 19 | class Solution(object): 20 | def compareVersion(self, version1, version2): 21 | """ 22 | :type version1: str 23 | :type version2: str 24 | :rtype: int 25 | """ 26 | v1 = version1.split('.') 27 | v2 = version2.split('.') 28 | v1 = [int(x) for x in v1] 29 | v2 = [int(x) for x in v2] 30 | 31 | len1 = len(v1) 32 | len2 = len(v2) 33 | lenMax = max(len1, len2) 34 | for x in range(lenMax): 35 | v1Token = 0 36 | if x < len1: 37 | v1Token = v1[x] 38 | v2Token = 0 39 | if x < len2: 40 | v2Token = v2[x] 41 | if v1Token > v2Token: 42 | return 1 43 | elif v1Token < v2Token: 44 | return -1 45 | return 0 46 | 47 | ``` 48 | -------------------------------------------------------------------------------- /1-250/213._house_robber_ii.md: -------------------------------------------------------------------------------- 1 | ###213. House Robber II 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | Medium 10 | 11 | 思路: 12 | 13 | 跟house robber 1 类似,但是加了一些限制,抢到第 n-1 家最大两种可能,抢第 n-1 家和不抢第 n-1 家。 14 | 15 | 0, 1, 2, 3, 4, 5, 6 ... n-1 16 | 17 | 18 | 所以状态转移方程写成二维的更好来求,从第i家抢到第j家的状态转移方程 19 | 20 | 21 | nums[j] ,j = i 22 | dp[i][j] = max(nums[i], nums[i+1]) , j = i +1 23 | max(dp[i][j-2] + nums[j], dp[i][j-1]), j > i+1 24 | 25 | 26 | 27 | Show me the code 28 | 29 | 30 | AC代码 31 | 32 | ``` 33 | class Solution(object): 34 | def rob(self, nums): 35 | """ 36 | :type nums: List[int] 37 | :rtype: int 38 | """ 39 | n = len(nums) 40 | if n == 0 : return 0 41 | if n == 1 : return nums[0] 42 | if n == 2 : return max(nums[0],nums[1]) 43 | 44 | dp = [[0 for i in range(n)] for j in range(n)] 45 | 46 | for i in range(n): 47 | for j in range(i,n): 48 | if j == i: 49 | dp[i][j] = nums[j] 50 | elif j == i + 1: 51 | dp[i][j] = max(nums[i],nums[i+1]) 52 | else: 53 | dp[i][j] = max(dp[i][j-2] + nums[j], dp[i][j-1]) 54 | 55 | # print dp 56 | # rob without n-1, or rob with n-1 57 | val = max(dp[0][n-2], dp[1][n-3] + nums[n-1]) 58 | 59 | return val 60 | 61 | ``` -------------------------------------------------------------------------------- /251-500/263._ugly_number.md: -------------------------------------------------------------------------------- 1 | ###263. Ugly Number 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 13 | 思路: 14 | 15 | 因为其prime factors 只包括 2, 3, 5,所以比如如果能被2 整除, n = n / 2, 直到不能被2整除,然后同样对3,5检验,如果最终结果为1,那么就是ugly number,否则不过关 16 | 17 | 18 | 注意一下边界条件,当num为0的时候,return一下False 19 | 20 | ``` 21 | class Solution(object): 22 | def isUgly(self, num): 23 | """ 24 | :type num: int 25 | :rtype: bool 26 | """ 27 | if num == 0 : return False 28 | while num % 2 == 0: 29 | num = num / 2 30 | while num % 3 == 0: 31 | num = num / 3 32 | while num % 5 == 0: 33 | num = num / 5 34 | if num == 1: 35 | return True 36 | return False 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /251-500/265. Paint House II.md: -------------------------------------------------------------------------------- 1 | ### 265. Paint House II 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 难度: 9 | 10 | Hard 11 | 12 | 13 | 14 | 思路: 15 | 16 | 感觉不像hard 题,知道为啥hard了,因为can you solve it in O(nk) runtime 17 | 18 | 数组 dp\[x][k] 代表第x个房子paint 0..k的值 19 | 20 | 21 | 22 | 用paint house 1 改的AC代码: 23 | 24 | 不过这个时间复杂度是O(nkk)吧 25 | 26 | 27 | 28 | ``` 29 | class Solution(object): 30 | def minCostII(self, costs): 31 | """ 32 | :type costs: List[List[int]] 33 | :rtype: int 34 | """ 35 | n = len(costs) 36 | if n == 0 : return 0 37 | elif n == 1 : return min (costs[0]) 38 | else: 39 | k = len(costs[0]) if n else 0 40 | dp = [[0 for i in range(k)] for j in range(n)] 41 | 42 | dp[0] = costs[0] 43 | 44 | for i in range(1,n): 45 | for j in range(0,k): 46 | minVal = float('inf') 47 | for m in range(0,k): 48 | if m != j and dp[i-1][m] < minVal: 49 | minVal = dp[i-1][m] 50 | dp[i][j] = minVal + costs[i][j] 51 | 52 | return min(dp[-1]) 53 | ``` 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /251-500/266. Palindrome Permutation.md: -------------------------------------------------------------------------------- 1 | ### 266. Palindrome Permutation 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 难度 : Easy 9 | 10 | 11 | 12 | 思路: 13 | 14 | hint 已经提示的很明显。数单字个数来处理 15 | 16 | 17 | 18 | AC代码 19 | 20 | 21 | 22 | ``` 23 | class Solution(object): 24 | def canPermutePalindrome(self, s): 25 | """ 26 | :type s: str 27 | :rtype: bool 28 | """ 29 | lookup = {} 30 | 31 | for char in s: 32 | lookup[char] = lookup.get(char,0) + 1 33 | 34 | res = 0 35 | 36 | for char, cnt in lookup.items(): 37 | if cnt % 2 == 0 : 38 | continue 39 | else: 40 | res += 1 41 | 42 | return res < 2 43 | ``` 44 | 45 | ​ 46 | 47 | -------------------------------------------------------------------------------- /251-500/276. Paint Fence.md: -------------------------------------------------------------------------------- 1 | ### 276. Paint Fence 2 | 3 | 题目: 4 | 5 | 6 | 难度: 7 | Easy 8 | 9 | 思路: 10 | 11 | 先解释一下题目意思: fence 栅栏, post 柱子 , no more than two adjacent fence posts have the same color.(一开始看漏,没有看到more than,以为相邻就不能同色)。 12 | 13 | 本来想画格子找规律,结果走偏了,所以老老实实写递推关系式,貌似是这样的 14 | 15 | - n = 0 : 全为0 16 | - n = 1 : 有 k种方式 17 | - n = 2 :有 k * k 种 18 | - 否则,第n个有两种可能, 跟 n-1 颜色不一样, 跟 n-1 颜色一样, fn = (k-1)fn-1 + (k-1) fn-2 19 | 20 | 21 | 22 | 画一下表:对一下递推关系式,正确✅ 23 | 24 | 25 | 26 | ``` 27 | n 28 | 0 1 2 3 4 29 | 0 0 0 0 0 0 30 | t 1 0 1 1 0 0 31 | 2 0 2 4 6 10 32 | 3 0 3 9 24 . 33 | 4 0 4 16 60 . 34 | ``` 35 | 36 | 37 | 38 | AC 代码 39 | 40 | ``` 41 | class Solution(object): 42 | def numWays(self, n, k): 43 | """ 44 | :type n: int 45 | :type k: int 46 | :rtype: int 47 | """ 48 | if n == 0: 49 | return 0 50 | else: 51 | if k == 0: return 0 52 | elif n == 1: return k 53 | elif n == 2 : return k * k 54 | else: 55 | dp = [0 for i in range(n+1)] 56 | dp[0] = 0 57 | dp[1] = k 58 | dp[2] = k * k 59 | 60 | for i in range(3,n+1): 61 | dp[i] = (k-1) * dp [i-1] + (k-1) * dp [i-2] 62 | return dp[-1] 63 | 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /251-500/278._First_Bad _Version.md: -------------------------------------------------------------------------------- 1 | ### 278. First Bad Version 2 | 3 | 4 | 5 | 6 | 7 | 题目: 8 | 9 | 10 | 11 | 12 | 难度 : Easy 13 | 14 | 15 | 16 | 思路: 17 | 18 | 根据 search for a range 改的 19 | 20 | 21 | 22 | ```python 23 | class Solution(object): 24 | def firstBadVersion(self, n): 25 | """ 26 | :type n: int 27 | :rtype: int 28 | """ 29 | l, r = 0, n - 1 30 | while l <= r: 31 | mid = l + ((r - l) >> 2) 32 | if not isBadVersion(mid): 33 | l = mid + 1 34 | else: 35 | r = mid - 1 36 | return l 37 | ``` 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /251-500/290._word_pattern.md: -------------------------------------------------------------------------------- 1 | ###290. Word Pattern 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 4.pattern = "abba", str = "dog dog dog dog" should return false. 10 | 11 | 因为这个的限制,所以中间加了一个loop用来查询是否这个a对应的已经出现过了。 12 | 13 | 不过其实也可以用两个dictionary来处理,可以O(n^3) -> O(n^2) 14 | 15 | 16 | ``` 17 | class Solution(object): 18 | def wordPattern(self, pattern, str): 19 | """ 20 | :type pattern: str 21 | :type str: str 22 | :rtype: bool 23 | """ 24 | strList = str.split(' ') 25 | if len(pattern) != len(strList): 26 | return False 27 | lookup = {} 28 | for i in range(len(strList)): 29 | if pattern[i] not in lookup: 30 | for key in lookup: 31 | if lookup[key] == strList[i]: 32 | return False 33 | lookup[pattern[i]] = strList[i] 34 | elif lookup[pattern[i]] != strList[i]: 35 | return False 36 | 37 | return True 38 | 39 | ``` 40 | 41 | 42 | 另外看到一段非常简短代码,使用了map函数,有待学习 43 | -------------------------------------------------------------------------------- /251-500/292._nim_game.md: -------------------------------------------------------------------------------- 1 | ### 292. Nim Game 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 对于总是优先开始的那方 14 | 15 | 16 | - 有一到三块,总是赢 17 | - 有四块,总是输 18 | - 有五块,总是赢 19 | 20 | 所以如果自己想赢,总是要迫使对方拿之后,给自己遗留5块,或者三块以及以下。 21 | 22 | - 如果是六块: 23 | - 拿一块,对方五块,对方赢 24 | - 拿两块,对方余下四块,我方赢 25 | - 拿三块,余三块,对方赢 26 | 27 | - 七块: 28 | - 拿三块,余四块,迫使对方输,总是赢 29 | 30 | 本打算用递归来看,因为对方也可以重复使用这个函数,但是会超时,所以就看了一下hint 31 | 32 | 33 | - n <= 3 能赢 √ 34 | - n == 4 总输 35 | - n = 5,6,7 总赢 36 | - n == 8, 先手如何选,总可以转成5,6,7 对方总会赢 37 | 38 | 39 | 所以 n % 4 == 0 时候,先手必输 40 | 41 | 简直是啊,有些游戏就是这样来必赢的啊,没想到你是这样的题目 42 | 43 | 44 | 45 | ``` 46 | class Solution(object): 47 | def canWinNim(self, n): 48 | """ 49 | :type n: int 50 | :rtype: bool 51 | """ 52 | return n % 4 != 0 53 | ``` 54 | 55 | 56 | -------------------------------------------------------------------------------- /251-500/293._Flip_Game.md: -------------------------------------------------------------------------------- 1 | ### 293. Flip Game 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路 13 | 14 | 15 | 16 | 17 | ```python 18 | class Solution(object): 19 | def generatePossibleNextMoves(self, s): 20 | """ 21 | :type s: str 22 | :rtype: List[str] 23 | """ 24 | res = [] 25 | if not s or len(s) <= 1: 26 | return res 27 | for i in range(len(s)-1): 28 | if s[i] == '+' and s[i+1] == '+': 29 | res.append(s[:i]+'--'+s[i+2:]) 30 | return res 31 | ``` 32 | 33 | 这里要注意一个点:s[i+2:] 虽然i+2取不到,但是s[i+2:]就是一个空字符串。 34 | 35 | -------------------------------------------------------------------------------- /251-500/296. Best Meeting Point.md: -------------------------------------------------------------------------------- 1 | ### 296. Best Meeting Point 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度 : Hard 9 | 10 | 11 | 12 | 思路: 13 | 14 | 提示是先从一维开始,其实一开始是略迷茫的,因为如果两个点,那么只要在这两个之间,一定就是最小值,线段长度。 15 | 16 | 不过倘若点增加到三个,那么就是第三个点处。 17 | 18 | 19 | 20 | 然后发现了一个很棒的stackoverflow page 21 | 22 | 23 | 24 | 25 | 26 | 因为一开始理解错误二维数组的输入,以为是给的locs这样的数组,所以直接这样写了,然后发现给的是格子,所以但是还是偷懒这样写了。 27 | 28 | 29 | 30 | AC 代码 31 | 32 | ``` 33 | class Solution(object): 34 | def minTotalDistance(self, grid): 35 | """ 36 | :type grid: List[List[int]] 37 | :rtype: int 38 | """ 39 | res = 0 40 | locs = [] 41 | 42 | m = len(grid) 43 | n = len(grid[0]) if m else 0 44 | 45 | for i in range(m): 46 | for j in range(n): 47 | if grid[i][j] == 1: 48 | locs.append([i,j]) 49 | 50 | 51 | locs.sort(key = lambda point: point[0]) 52 | x = locs[len(locs)/2][0] 53 | for point in locs: 54 | res += abs(point[0] - x) 55 | 56 | locs.sort(key = lambda point: point[1]) 57 | y = locs[len(locs)/2][1] 58 | for point in locs: 59 | res += abs(point[1] - y) 60 | 61 | return res 62 | ``` 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /251-500/303._range_sum_query_-_immutable.md: -------------------------------------------------------------------------------- 1 | ###303. Range Sum Query - Immutable 2 | 3 | 题目: 4 | 5 | 6 | 7 | tag : DP 8 | 难度 : Easy 9 | 10 | 11 | 12 | ``` 13 | sum(i, j) = nums[i] j = i 14 | sum(i,j) = sum[i,j-1] + nums[j] j > i 15 | 16 | ``` 17 | 18 | Python代码 19 | 20 | ``` 21 | 22 | class NumArray(object): 23 | def __init__(self, nums): 24 | """ 25 | initialize your data structure here. 26 | :type nums: List[int] 27 | """ 28 | self.sums = nums 29 | for i in range(1, len(self.sums)): 30 | self.sums[i] = self.sums[i-1] + self.sums[i] 31 | 32 | 33 | 34 | 35 | def sumRange(self, i, j): 36 | """ 37 | sum of elements nums[i..j], inclusive. 38 | :type i: int 39 | :type j: int 40 | :rtype: int 41 | """ 42 | if i == 0 : 43 | return self.sums[j] 44 | else : 45 | return self.sums[j] - self.sums[i-1] 46 | 47 | ``` -------------------------------------------------------------------------------- /251-500/322._Coin_Change.md: -------------------------------------------------------------------------------- 1 | # 322. Coin Change 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/coin-change/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. 15 | 16 | Example 1: 17 | 18 | Input: coins = [1, 2, 5], amount = 11 19 | Output: 3 20 | Explanation: 11 = 5 + 5 + 1 21 | Example 2: 22 | 23 | Input: coins = [2], amount = 3 24 | Output: -1 25 | Note: 26 | You may assume that you have an infinite number of each kind of coin. 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | ******- 时间复杂度: O(N*amount)******- 空间复杂度: O(amount)****** 33 | 34 | DP入门 35 | 36 | 递推方程式: dp[i] = min(dp[i], dp[i-coins[j]]+1), coins[j] 是硬币的面额 37 | 38 | 39 | 40 | ```python 41 | class Solution(object): 42 | def coinChange(self, coins, amount): 43 | """ 44 | :type coins: List[int] 45 | :type amount: int 46 | :rtype: int 47 | """ 48 | dp = [amount+1] * (amount+1) 49 | dp[0] = 0 50 | for i in range(1, amount+1): 51 | for coin in coins: 52 | if coin <= i: 53 | dp[i] = min(dp[i], dp[i-coin]+1) 54 | return -1 if dp[-1] == amount + 1 else dp[-1] 55 | ``` 56 | 57 | -------------------------------------------------------------------------------- /251-500/324._Wiggle_Sort_II.md: -------------------------------------------------------------------------------- 1 | ### 324. Wiggle Sort II 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Medium 11 | 12 | 思路: 13 | 14 | 首先这道题和[Wiggle Sort](https://github.com/Lisanaaa/thinking_in_lc/blob/master/280._Wiggle_Sort.md)要求不一样,不能有等于, 15 | 所以如果碰到一串```‘1,1,1,1,1,1’```,当调换顺序时候还是不会满足。 16 | 17 | 因此我们用新方法,首先将原数组排序,然后大的那一半数字降序插在奇数```index```上,小的那一半数字降序插在偶数```index```上 18 | 19 | 20 | ```python 21 | class Solution(object): 22 | def wiggleSort(self, nums): 23 | """ 24 | :type nums: List[int] 25 | :rtype: void Do not return anything, modify nums in-place instead. 26 | """ 27 | nums.sort() 28 | half = len(nums[::2]) 29 | nums[::2], nums[1::2] = nums[:half][::-1], nums[half:][::-1] 30 | ``` 31 | 32 | 33 | ### Follow up 34 | O(n) time, O(1) space 35 | 36 | 思路: 37 | 首先想到的是将我们上面的排序方法用堆排序实现即可,建堆O(n),调整堆O(lgN) 38 | 39 | 40 | ```python 41 | 42 | ``` 43 | -------------------------------------------------------------------------------- /251-500/325._Maximum_Size_Subarray_Sum_Equals_k.md: -------------------------------------------------------------------------------- 1 | # 325. Maximum Size Subarray Sum Equals k 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead. 15 | 16 | Note: 17 | The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range. 18 | 19 | Example 1: 20 | 21 | Input: nums = [1, -1, 5, -2, 3], k = 3 22 | Output: 4 23 | Explanation: The subarray [1, -1, 5, -2] sums to 3 and is the longest. 24 | Example 2: 25 | 26 | Input: nums = [-2, -1, 2, 1], k = 1 27 | Output: 2 28 | Explanation: The subarray [-1, 2] sums to 1 and is the longest. 29 | Follow Up: 30 | Can you do it in O(n) time? 31 | ``` 32 | 33 | ## 解题方案 34 | 35 | > 思路 1 36 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 37 | 38 | 39 | 前缀和+字典的方法 40 | 41 | ```python 42 | class Solution(object): 43 | def maxSubArrayLen(self, nums, k): 44 | """ 45 | :type nums: List[int] 46 | :type k: int 47 | :rtype: int 48 | """ 49 | res, sums = 0, 0 # res and the accumulative value of nums 50 | lookup = {0: -1} # key is accumlative sum, value is index 51 | for i, num in enumerate(nums): 52 | sums += num 53 | if sums - k in lookup: 54 | res = max(res, i-lookup[sums-k]) # when key = 0, we should just use i+1 55 | if sums not in lookup: 56 | lookup[sums] = i 57 | return res 58 | ``` 59 | 60 | 61 | -------------------------------------------------------------------------------- /251-500/326._power_of_three.md: -------------------------------------------------------------------------------- 1 | ### 326. Power of Three 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 9 | 难度 : Easy 10 | 11 | 12 | 直接就上的递归 13 | 14 | ```python 15 | class Solution(object): 16 | def isPowerOfThree(self,n): 17 | """ 18 | :type n: int 19 | :rtype: bool 20 | """ 21 | if n <= 0: 22 | return False 23 | if n == 1: 24 | return True 25 | if n % 3 == 0: 26 | return self.isPowerOfThree(n/3) 27 | return False 28 | 29 | ``` 30 | 31 | 有一个follow up,可否不用 loop/recusion 32 | 33 | 看到了取巧的办法,因为是Given an integer,是有范围的(<2147483648),存在能输入的最大的3的幂次,即 3^19=1162261467。 34 | 35 | 只用检查是否能被这个数整除 36 | 37 | 38 | ```python 39 | class Solution(object): 40 | def isPowerOfThree(self, n): 41 | """ 42 | :type n: int 43 | :rtype: bool 44 | """ 45 | return n > 0 and pow(3, 19) % n == 0 46 | 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /251-500/334._increasing_triplet_subsequence.md: -------------------------------------------------------------------------------- 1 | ###334. Increasing Triplet Subsequence 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 11 | 思路: 12 | 13 | 用longest increasing subsequence来求,超时 14 | 15 | ``` 16 | class Solution(object): 17 | def increasingTriplet(self, nums): 18 | """ 19 | :type nums: List[int] 20 | :rtype: bool 21 | """ 22 | if not nums: return False 23 | n = len(nums) 24 | dp = [1 for i in range(n)] 25 | for i in range(1,n): 26 | for j in range(i): 27 | if nums[i] > nums[j] : 28 | dp[i] = max(dp[i],dp[j] + 1) 29 | if dp[i] >= 3: 30 | return True 31 | 32 | return False 33 | ``` 34 | 35 | 于是转而用Third Maximum Number的方法,维护一个当前最小和当前第二小,当碰到当前比较大,返回True,否则一圈走下来依旧不能满足,返回false. 36 | 37 | 想一下,如果不是求三个增长,如果是求两个的话,那么一定想到的是保存当前最小值,那么一旦后方遇到一个比较大的,就这样处理掉了。 38 | 39 | 所以对于任何一个num来说,有三种可能: 40 | 41 | - 小于当前的最小值,那么更新当前最小值 42 | - 小于当前第二小值,更新当前第二小值 43 | - 如果以上两种都不是,那么是大于当前第二小值和最小值,于是这样就true 44 | 45 | 所以是求四个增长也是类似的么 46 | 47 | AC代码 48 | 49 | ``` 50 | class Solution(object): 51 | def increasingTriplet(self, nums): 52 | """ 53 | :type nums: List[int] 54 | :rtype: bool 55 | """ 56 | # m - min, sm - second min 57 | m, sm = float('inf'), float('inf') 58 | 59 | for num in nums: 60 | print m, sm 61 | if m >= num: 62 | m = num 63 | elif sm >= num: 64 | sm = num 65 | else: 66 | return True 67 | return False 68 | ``` 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /251-500/337._house_robber_iii.md: -------------------------------------------------------------------------------- 1 | ###337. House Robber III 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | Medium 10 | 11 | 思路: 12 | 13 | 参考 14 | 15 | 16 | 这个解法好像有点厉害 17 | 18 | 从root开始抢起来,最大能抢到的两个可能: 抢root和不抢root 19 | 20 | - rob_root = max(rob_L + rob_R , no_rob_L + no_nob_R + root.val) 21 | - no_rob_root = rob_L + rob_R 22 | 23 | 24 | 这个递归写起来就很厉害了 25 | 26 | 27 | ``` 28 | class Solution(object): 29 | def rob(self, root): 30 | """ 31 | :type root: TreeNode 32 | :rtype: int 33 | """ 34 | def dfs(root): 35 | if not root: return 0, 0 36 | rob_L, no_rob_L = dfs(root.left) 37 | rob_R, no_rob_R = dfs(root.right) 38 | return max(no_rob_R + no_rob_L + root.val , rob_L + rob_R), rob_L + rob_R 39 | 40 | return dfs(root)[0] 41 | 42 | ``` 43 | 44 | 对于每个node,我们return的是从这个node能抢到的最大值,以及不抢它能获得的最大值,这个递归简直我服 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /251-500/339. Nested List Weight Sum.md: -------------------------------------------------------------------------------- 1 | ### 339. Nested List Weight Sum 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 难度: 9 | Easy 10 | 11 | 思路: 12 | 13 | 一开始没认真读题,直接上手开写: 14 | 15 | ``` 16 | class Solution(object): 17 | def depthSum(self, nestedList): 18 | """ 19 | :type nestedList: List[NestedInteger] 20 | :rtype: int 21 | """ 22 | def dfs(nestedList): 23 | for item in nestedList: 24 | if item.isInteger(): 25 | self.res += item.getInteger() 26 | else: 27 | dfs(item.getList()) 28 | self.res = 0 29 | dfs(nestedList) 30 | return self.res 31 | ``` 32 | 33 | 34 | 35 | 然后注意到要weight by its depth. 36 | 37 | 38 | 39 | AC 40 | 41 | ``` 42 | class Solution(object): 43 | def depthSum(self, nestedList): 44 | """ 45 | :type nestedList: List[NestedInteger] 46 | :rtype: int 47 | """ 48 | def dfs(nestedList,depth): 49 | for item in nestedList: 50 | if item.isInteger(): 51 | self.res += item.getInteger() * depth 52 | else: 53 | dfs(item.getList(), depth+1) 54 | self.res = 0 55 | dfs(nestedList,1) 56 | return self.res 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /251-500/340._Longest_Substring_with_At_Most_K_Distinct_Characters.md: -------------------------------------------------------------------------------- 1 | # 340. Longest Substring with At Most K Distinct Characters 2 | 3 | **难度: Hard** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | 15 | Given a string, find the length of the longest substring T that contains at most k distinct characters. 16 | 17 | Example 1: 18 | 19 | Input: s = "eceba", k = 2 20 | Output: 3 21 | Explanation: T is "ece" which its length is 3. 22 | Example 2: 23 | 24 | Input: s = "aa", k = 1 25 | Output: 2 26 | Explanation: T is "aa" which its length is 2. 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 33 | 34 | 35 | 思路见第159题 36 | 37 | ```python 38 | class Solution(object): 39 | def lengthOfLongestSubstringKDistinct(self, s, k): 40 | """ 41 | :type s: str 42 | :type k: int 43 | :rtype: int 44 | """ 45 | maps = {} 46 | begin, end, counter, length = 0, 0, 0, 0 47 | while end < len(s): 48 | maps[s[end]] = maps.get(s[end], 0) + 1 49 | if maps[s[end]] == 1: 50 | counter += 1 51 | end += 1 # end 永远指向下一个待处理的字符 52 | while counter > k: 53 | maps[s[begin]] -= 1 54 | if maps[s[begin]] == 0: 55 | counter -= 1 56 | begin += 1 57 | length = max(length, end - begin) # 因此这里是```end - begin```而不是```end - begin + 1``` 58 | return length 59 | ``` 60 | -------------------------------------------------------------------------------- /251-500/342._Power_of_Four.md: -------------------------------------------------------------------------------- 1 | ### 342. Power of Four 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 10 | 难度 : Easy 11 | 12 | 继续照抄power of three 13 | 14 | ```python 15 | class Solution(object): 16 | def isPowerOfFour(self, num): 17 | """ 18 | :type num: int 19 | :rtype: bool 20 | """ 21 | if num <= 0 : 22 | return False 23 | if num == 1: 24 | return True 25 | if num % 4 == 0: 26 | return self.isPowerOfFour(num/4) 27 | return False 28 | 29 | ``` 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /251-500/344._reverse_string.md: -------------------------------------------------------------------------------- 1 | ### 344. Reverse String 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 思路: 13 | 14 | 不要脸的python AC code: 15 | 16 | 17 | ```python 18 | class Solution(object): 19 | def reverseString(self, s): 20 | """ 21 | :type s: str 22 | :rtype: str 23 | """ 24 | return s[::-1] 25 | ``` 26 | 27 | 因为python不支持item assignment 28 | 29 | 所以如果非要用two pointer来做的话,那么会是这样 30 | 31 | ```python 32 | class Solution(object): 33 | def reverseString(self, s): 34 | """ 35 | :type s: str 36 | :rtype: str 37 | """ 38 | lst = list(s) 39 | n = len(lst) 40 | start, end = 0, n - 1 41 | 42 | while start < end: 43 | lst[end], lst[start] = lst[start],lst[end] 44 | start += 1 45 | end -= 1 46 | return ''.join(lst) 47 | ``` 48 | -------------------------------------------------------------------------------- /251-500/345._Reverse_Vowels_of_a_String.md: -------------------------------------------------------------------------------- 1 | ### 345. Reverse Vowels of a String 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 14 | 思路 15 | 16 | 字符串不可变,所以用list代替,最后join 17 | 18 | 19 | 20 | ```python 21 | class Solution(object): 22 | def reverseVowels(self, s): 23 | """ 24 | :type s: str 25 | :rtype: str 26 | """ 27 | vowels = 'aeiou' 28 | string = list(s) 29 | i, j = 0, len(s) -1 30 | while i <= j: 31 | if string[i].lower() not in vowels: 32 | i += 1 33 | elif string[j].lower() not in vowels: 34 | j -= 1 35 | else: 36 | string[i], string[j] = string[j], string[i] 37 | i += 1 38 | j -= 1 39 | return ''.join(string) 40 | ``` 41 | 42 | 正则版本 43 | 44 | ```python 45 | class Solution(object): 46 | def reverseVowels(self, s): 47 | """ 48 | :type s: str 49 | :rtype: str 50 | """ 51 | vowels = re.findall('(?i)[aeiou]', s) 52 | return re.sub('(?i)[aeiou]', lambda m: vowels.pop(), s) 53 | ``` 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /251-500/349._intersection_of_two_arrays.md: -------------------------------------------------------------------------------- 1 | ### 349. Intersection of Two Arrays 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 13 | Python一句话作弊 14 | 15 | ```python 16 | class Solution(object): 17 | def intersection(self, nums1, nums2): 18 | """ 19 | :type nums1: List[int] 20 | :type nums2: List[int] 21 | :rtype: List[int] 22 | """ 23 | return list(set(nums1).intersection(nums2)) 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /251-500/350._intersection_of_two_arrays_ii.md: -------------------------------------------------------------------------------- 1 | ### 350. Intersection of Two Arrays II 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | sort之后用了双指针来走和看 14 | 15 | 16 | ```python 17 | class Solution(object): 18 | def intersect(self, nums1, nums2): 19 | """ 20 | :type nums1: List[int] 21 | :type nums2: List[int] 22 | :rtype: List[int] 23 | """ 24 | nums1.sort() 25 | nums2.sort() 26 | 27 | l1 = len(nums1) 28 | l2 = len(nums2) 29 | 30 | p1 = 0 31 | p2 = 0 32 | 33 | res = [] 34 | 35 | while p1 < l1 and p2 < l2: 36 | if nums1[p1] < nums2[p2]: 37 | p1 += 1 38 | elif nums1[p1] > nums2[p2]: 39 | p2 += 1 40 | else: 41 | res.append(nums1[p1]) 42 | p1 += 1 43 | p2 += 1 44 | return res 45 | ``` 46 | 47 | 两行版本 48 | ```python 49 | class Solution(object): 50 | def intersect(self, nums1, nums2): 51 | """ 52 | :type nums1: List[int] 53 | :type nums2: List[int] 54 | :rtype: List[int] 55 | """ 56 | a, b = map(collections.Counter, (nums1, nums2)) 57 | return list((a & b).elements()) 58 | ``` 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /251-500/364. Nested List Weight Sum II.md: -------------------------------------------------------------------------------- 1 | ### 364. Nested List Weight Sum II 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 难度: 9 | Medium 10 | 11 | 思路: 12 | 13 | 14 | 15 | 跟 Nested List Weight Sum I 的区别是这个是从不是数depth,是数层的高度: 16 | 17 | 18 | 19 | 比较naive的AC代码: 20 | 21 | ``` 22 | class Solution(object): 23 | def depthSumInverse(self, nestedList): 24 | """ 25 | :type nestedList: List[NestedInteger] 26 | :rtype: int 27 | """ 28 | def level(nestedList,height): 29 | self.level = max(height, self.level) 30 | for item in nestedList: 31 | if not item.isInteger(): 32 | level(item.getList(), height + 1) 33 | 34 | def dfs(nestedList, height): 35 | for item in nestedList: 36 | if item.isInteger(): 37 | self.res += item.getInteger() * height 38 | else: 39 | dfs(item.getList(),height - 1) 40 | 41 | self.level = 1 42 | self.res = 0 43 | level(nestedList,1) 44 | dfs(nestedList, self.level) 45 | return self.res 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /251-500/367._valid_perfect_square.md: -------------------------------------------------------------------------------- 1 | ###367. Valid Perfect Square 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 13 | 直接用循环做也可以AC 14 | 15 | 16 | ``` 17 | class Solution(object): 18 | def isPerfectSquare(self, num): 19 | """ 20 | :type num: int 21 | :rtype: bool 22 | """ 23 | if num == 1 or num == 4 : return True 24 | for i in xrange(num//2): 25 | if i*i == num: 26 | return True 27 | elif i*i > num: 28 | return False 29 | return False 30 | 31 | ``` 32 | 33 | 然后发现有传说中的牛顿法 34 | 35 | 有待阅读,然后还有二分法 36 | 37 | ``` 38 | r = x 39 | while r*r > x: 40 | r = (r + x/r) / 2 41 | return r*r == x 42 | ``` -------------------------------------------------------------------------------- /251-500/371._sum_of_two_integers.md: -------------------------------------------------------------------------------- 1 | ###371. Sum of Two Integers 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路 13 | 14 | 15 | 谷歌答案 16 | 17 | 18 | 位运算 19 | 20 | ``` 21 | XOR 22 | x y output 23 | 0 0 0 24 | 1 0 1 25 | 0 1 1 26 | 1 1 0 27 | 28 | 29 | AND 30 | x y output 31 | 0 0 0 32 | 1 0 1 33 | 0 1 1 34 | 1 1 1 35 | 36 | ``` 37 | 38 | 如果对x和y来做加法(x和y都是一位的),那么末位会是x xor y,进位会是x and y 39 | 40 | 41 | 42 | 43 | 44 | python没有左移,用c++来看 45 | 46 | ``` 47 | class Solution { 48 | public: 49 | int getSum(int a, int b) { 50 | while (b != 0 ){ 51 | int c = a & b; 52 | a = a ^ b; 53 | b = c << 1; 54 | } 55 | return a; 56 | } 57 | }; 58 | ``` 59 | 60 | 实际上看到答案还是没有那么明白的,还是动手算算 61 | 62 | 63 | 64 | ``` 65 | a = 6 (0110) 66 | b = 15 (1111) 67 | 68 | 69 | 1st 70 | --------- 71 | carry = a & b = 0110 72 | a = a ^ b = 1001 73 | b = 1100 74 | 75 | 76 | 2nd 77 | --------- 78 | carry = a & b = 1000 79 | a = a ^ b = 0101 80 | b = 10000 81 | 82 | 83 | 3rd 84 | ---------- 85 | 86 | carry = a & b = 0 87 | a = a ^ b = 10101 88 | b = 0 89 | 90 | 这个时候a 的值是2^4 + 2^2 + 2^0 = 16+4+1 = 21 91 | ``` 92 | 93 | 虽然convence了我自己,但是表示依旧迷茫ing 94 | 95 | 也知道位运算需要待补啊 -------------------------------------------------------------------------------- /251-500/374._Guess_Number_Higher_or_Lower.md: -------------------------------------------------------------------------------- 1 | ### 374. Guess Number Higher or Lower 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路 13 | 14 | 二分 15 | 16 | ```python 17 | class Solution(object): 18 | def guessNumber(self, n): 19 | """ 20 | :type n: int 21 | :rtype: int 22 | """ 23 | l, r = 1, n 24 | while l <= r: 25 | mid = l + ((r - l) >> 2) 26 | if guess(mid) == 1: 27 | l = mid + 1 28 | elif guess(mid) == -1: 29 | r = mid - 1 30 | else: 31 | return mid 32 | ``` 33 | 34 | 35 | -------------------------------------------------------------------------------- /251-500/382._linked_list_random_node.md: -------------------------------------------------------------------------------- 1 | 2 | ###382. Linked List Random Node 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | 11 | Medium 12 | 13 | 14 | 15 | tag:reservoir sampling 水塘抽样 16 | 17 | 18 | 思路: 19 | 20 | n选k 21 | 22 | 23 | 这样来看,有k个元素,那么这个时候全部选中,当第k+1个元素进来的时候,生成一个随机数r,如果 r <= k,那么用它来替换第r个元素 24 | 25 | 那么r被替换掉的概率是 1 / k + 1, 不被替换掉的概率是 k / k + 1 (不生成r) 26 | 27 | k+2来继续: 被替换掉的概率 1 / k + 2, 不被替换掉的概率 (k + 1) / (k+2) 28 | 29 | 所以最终被选中的(不被替换掉的概率是) k / n 30 | 31 | 随机 √ 32 | 33 | 34 | 针对这道题目来看 35 | 36 | - 一开始选head为choice 37 | - 出现第二个,生成[1,2]之间的随机数,如果r = 2,则用新的来替换choice 38 | - 出现第三个,生成[1,2,3]之间的随机数,如果r = 3,则替换 39 | 40 | 再写简单一点就是 41 | 42 | 43 | 每次以 1/i 来决定是否用新的元素来替换选中元素,那么就是 i - 1 / i 不替换,它之前被选中的概率就是 1 / i-1 ,所以最终被选中的概率是 1/i 44 | 45 | 这个对于linked list更优之处在于它不用reverse 46 | 47 | 时间复杂度 O(N), 空间复杂度O(K) 48 | 49 | 50 | 然后AC 51 | 52 | 53 | ``` 54 | class Solution(object): 55 | 56 | def __init__(self, head): 57 | """ 58 | @param head The linked list's head. 59 | Note that the head is guaranteed to be not null, so it contains at least one node. 60 | :type head: ListNode 61 | """ 62 | self.head = head 63 | 64 | def getRandom(self): 65 | """ 66 | Returns a random node's value. 67 | :rtype: int 68 | """ 69 | choice = self.head 70 | cur = self.head 71 | i = 1 72 | while cur.next: 73 | cur = cur.next 74 | i += 1 75 | rd = random.randint(1,i) 76 | if rd == i: 77 | choice = cur 78 | return choice.val 79 | ``` 80 | -------------------------------------------------------------------------------- /251-500/383._ransom_note.md: -------------------------------------------------------------------------------- 1 | ### 383. Ransom Note 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 10 | 11 | 略微想了一下,用了一个dictionary来存magazine里面的单字出现的个数,然后来对应check是否可以用来组成ransomNote 12 | 13 | 14 | ```python 15 | class Solution(object): 16 | def canConstruct(self, ransomNote, magazine): 17 | """ 18 | :type ransomNote: str 19 | :type magazine: str 20 | :rtype: bool 21 | """ 22 | maps = {} 23 | for i in magazine: 24 | if i in maps: 25 | maps[i] += 1 26 | else: 27 | maps[i] = 1 28 | for i in ransomNote: 29 | if i not in maps: 30 | return False 31 | else: 32 | maps[i] -= 1 33 | if maps[i] < 0: 34 | return False 35 | return True 36 | ``` 37 | 解法2: 38 | 39 | ```python 40 | class Solution(object): 41 | def canConstruct(self, ransomNote, magazine): 42 | """ 43 | :type ransomNote: str 44 | :type magazine: str 45 | :rtype: bool 46 | """ 47 | magCounter = collections.Counter(magazine) 48 | ranCounter = collections.Counter(ransomNote) 49 | for k in ranCounter: 50 | if ranCounter.get(k) > magCounter.get(k): 51 | return False 52 | return True 53 | ``` 54 | -------------------------------------------------------------------------------- /251-500/387._first_unique_character_in_a_string.md: -------------------------------------------------------------------------------- 1 | ### 387. First Unique Character in a String 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Easy 9 | 10 | 11 | 12 | 思路一: 13 | 14 | Python作弊法 15 | 16 | 用Python的Counter模块 17 | 18 | 可以参考 19 | 20 | 21 | 22 | 23 | ```python 24 | class Solution(object): 25 | def firstUniqChar(self, s): 26 | """ 27 | :type s: str 28 | :rtype: int 29 | """ 30 | d = collections.Counter(s) 31 | for x,c in enumerate(s): 32 | if d[c] == 1: 33 | return x 34 | return -1 35 | ``` 36 | 37 | 38 | 思路二: 39 | 40 | 利用问题的特性,因为只有可能是小写字母,所以可以用一个长度为26的array, 先数一遍char的数量,然后enumerate从左往右又来 41 | 42 | ```python 43 | class Solution(object): 44 | def firstUniqChar(self, s): 45 | """ 46 | :type s: str 47 | :rtype: int 48 | """ 49 | cnt = [0 for i in range(26)] 50 | for char in s: 51 | cnt[ord(char) - ord('a')] += 1 52 | 53 | for idx, char in enumerate(s): 54 | if cnt[ord(char) - ord('a')] == 1: 55 | return idx 56 | return -1 57 | 58 | ``` 59 | -------------------------------------------------------------------------------- /251-500/389._find_the_difference.md: -------------------------------------------------------------------------------- 1 | 2 | ### 389. Find the Difference 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | 11 | Easy 12 | 13 | 用个字典来记录,把s加进去,把t减掉,最后剩下那个要么个数为1,要么个数为-1 14 | 15 | ```python 16 | class Solution(object): 17 | def findTheDifference(self, s, t): 18 | """ 19 | :type s: str 20 | :type t: str 21 | :rtype: str 22 | """ 23 | res = {} 24 | for i in s: 25 | res[i] = res.get(i, 0) + 1 26 | for j in t: 27 | res[j] = res.get(j, 0) - 1 28 | for key in res: 29 | if abs(res[key]) == 1: # 这里用 abs 是因为新增加的那个字母在 s 中可能未出现过 30 | return key 31 | ``` 32 | 还有一个简单的方法 33 | ```python 34 | class Solution(object): 35 | def findTheDifference(self, s, t): 36 | """ 37 | :type s: str 38 | :type t: str 39 | :rtype: str 40 | """ 41 | from collections import Counter 42 | return list((Counter(t) - Counter(s)).keys()).pop() 43 | ``` 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /251-500/394._decode_string.md: -------------------------------------------------------------------------------- 1 | ###394. Decode String 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 9 | 难度: 10 | 11 | Medium 12 | 13 | 14 | 思路: 15 | 16 | 感觉像用栈做运算。 17 | 18 | s = "3[a2[c]]" 19 | 20 | ⬇️ 21 | 22 | s = 3 *( a + 2 * ( c ) ) 23 | 24 | 25 | 遇到非右括号全部入栈,碰到右括号出栈直到左括号,这个就算运算符2 → op2 26 | 然后检查,直到stack空掉或者碰到下一个非数字,这个就算运算符1 → op1 27 | 28 | 算出op1 和 op2 之后把这个res继续入栈。然后接着处理 29 | 30 | 31 | 代码不是很优美 32 | 33 | 34 | 35 | 36 | ``` 37 | class Solution(object): 38 | def decodeString(self, s): 39 | """ 40 | :type s: str 41 | :rtype: str 42 | """ 43 | 44 | s = list(s) 45 | stack = [] 46 | 47 | while s: 48 | char = s.pop(0) 49 | if char != ']': 50 | stack.append(char) 51 | else: 52 | op1, op2 = '','' 53 | popChar = stack.pop() 54 | while popChar != '[': 55 | op2 = popChar + op2 56 | popChar = stack.pop() 57 | 58 | while stack and stack[-1] in ['0','1','2','3','4','5','6','7','8','9']: 59 | popChar = stack.pop() 60 | op1 = popChar + op1 61 | 62 | res = int(op1) * op2 63 | 64 | for char in res: 65 | stack.append(char) 66 | 67 | return ''.join(stack) 68 | ``` 69 | 70 | 71 | -------------------------------------------------------------------------------- /251-500/401._binary_watch.md: -------------------------------------------------------------------------------- 1 | ###401. Binary Watch 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 13 | 思路: 14 | 15 | 16 | 一看到位操作,我的内心是拒绝的。 17 | 18 | 我也有想这样的想法,因为其实可以的组合并没有那么多,干脆枚举算了,然而也没有动手来写,直到被发了题解的截屏。 19 | 20 | 21 | ``` 22 | class Solution(object): 23 | def readBinaryWatch(self, num): 24 | """ 25 | :type num: int 26 | :rtype: List[str] 27 | """ 28 | hour = { 0 : ['0'], 29 | 1:['1','2','4','8'], 30 | 2:['3','5','6','9','10'], 31 | 3:['7','11'] 32 | } 33 | 34 | minute = { 0:['00'], 35 | 1: ['01','02','04','08','16','32'], 36 | 2: ['03','05','06','09','10','12','17','18','20','24','33','34','36','40','48'], 37 | 3: ['07','11','13','14','19','21','22','25','26','28','35','37','38','41','42','44','49','50','52','56'], 38 | 4: ['15','23','27','29','30','39','43','45','46','51','53','54','57','58'], 39 | 5: ['31','47','55','59'] 40 | } 41 | 42 | res = [] 43 | 44 | #num = num for hour + num for minute 45 | i = 0 46 | 47 | while i <= 3 and i <= num: 48 | if num - i <= 5: 49 | for str1 in hour[i]: 50 | for str2 in minute[num-i]: 51 | res.append(str1 + ':' + str2) 52 | i += 1 53 | return res 54 | ``` 55 | 56 | 57 | 关于循环那处,因为hour的led最多只有4个,所以这样写循环 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /251-500/413. Arithmetic Slices.md: -------------------------------------------------------------------------------- 1 | ### 413. Arithmetic Slices 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 10 | 难度 : Medium 11 | 12 | 13 | 14 | 思路: 15 | 16 | tag 是DP 17 | 18 | 数从 i 到 j 之间的这个arithmetic 数 19 | 20 | 我的方法时间复杂度比较高O(N^2),从 i 开始数它的arithmetic slice,每个i数一遍,到 j 21 | 22 | AC代码 23 | 24 | ``` 25 | class Solution(object): 26 | def numberOfArithmeticSlices(self, A): 27 | """ 28 | :type A: List[int] 29 | :rtype: int 30 | """ 31 | n = len(A) 32 | if n < 3: 33 | return 0 34 | else: 35 | res = 0 36 | for i in range(n-2): 37 | for j in range(i+2,n): 38 | if A[j] - A[j-1] == A[i+1] - A[i]: 39 | res += 1 40 | else: 41 | break 42 | return res 43 | ``` 44 | 45 | 46 | 47 | 应该可以优化到O(N) 48 | 49 | 不需要每个每个开始数,可以边数边移动 50 | 51 | 可以参考 52 | 53 | 54 | 55 | O(N) 代码 56 | 57 | ``` 58 | class Solution(object): 59 | def numberOfArithmeticSlices(self, A): 60 | """ 61 | :type A: List[int] 62 | :rtype: int 63 | """ 64 | n = len(A) 65 | if n < 3: 66 | return 0 67 | else: 68 | res, cnt = 0, 2 69 | for i in range(2, n): 70 | if A[i] - A[i-1] == A[i-1] - A[i-2]: 71 | print i, i-1, i-2 72 | cnt += 1 73 | else: 74 | if cnt > 2: 75 | res += (cnt-1) * (cnt-2) / 2 76 | cnt = 2 77 | if cnt > 2: res += (cnt-1) * (cnt-2) / 2 78 | return res 79 | 80 | 81 | ``` 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /251-500/414._third_maximum_number.md: -------------------------------------------------------------------------------- 1 | ###414. Third Maximum Number 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路: 13 | 14 | 用三个变量来记录,max, secondmax, thirdmax, 15 | 16 | - 遇到比max还大的就更新,当前max降级为secondmax,当前secondmax降级为thirdmax 17 | - 遇到比max小但是比secondmax大的也这样做降级处理 18 | - 更thirdmax 19 | 20 | 21 | AC代码 22 | 23 | 24 | ``` 25 | class Solution(object): 26 | def thirdMax(self, nums): 27 | """ 28 | :type nums: List[int] 29 | :rtype: int 30 | """ 31 | m, sm, tm = float('-inf'), float('-inf'), float('-inf') 32 | 33 | for num in nums: 34 | if num > m: 35 | tm = sm 36 | sm = m 37 | m = num 38 | elif num < m and num > sm: 39 | tm = sm 40 | sm = num 41 | elif num < m and num < sm and num > tm: 42 | tm = num 43 | 44 | return tm if tm != float('-inf') else m 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /251-500/415._add_strings.md: -------------------------------------------------------------------------------- 1 | # 415. Add Strings 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/add-strings/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | 15 | Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2. 16 | 17 | Note: 18 | 19 | The length of both num1 and num2 is < 5100. 20 | Both num1 and num2 contains only digits 0-9. 21 | Both num1 and num2 does not contain any leading zero. 22 | You must not use any built-in BigInteger library or convert the inputs to integer directly. 23 | ``` 24 | 25 | ## 解题方案 26 | 27 | > 思路 1 28 | 29 | 题目说不能直接将input转换为int,那我就一次只转换一位,真tm简单! 30 | 31 | ```python 32 | class Solution(object): 33 | def addStrings(self, num1, num2): 34 | """ 35 | :type num1: str 36 | :type num2: str 37 | :rtype: str 38 | """ 39 | def str2int(num): 40 | res = 0 41 | for i in range(len(num)-1, -1, -1): 42 | res += int(num[i]) * pow(10, len(num)-1-i) 43 | return res 44 | return str(str2int(num1) + str2int(num2)) 45 | ``` 46 | -------------------------------------------------------------------------------- /251-500/416._Partition_Equal_Subset_Sum.md: -------------------------------------------------------------------------------- 1 | # 416. Partition Equal Subset Sum 2 | **难度: 中等** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/partition-equal-subset-sum/description/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. 14 | 15 | Note: 16 | Each of the array element will not exceed 100. 17 | The array size will not exceed 200. 18 | Example 1: 19 | 20 | Input: [1, 5, 11, 5] 21 | 22 | Output: true 23 | 24 | Explanation: The array can be partitioned as [1, 5, 5] and [11]. 25 | Example 2: 26 | 27 | Input: [1, 2, 3, 5] 28 | 29 | Output: false 30 | 31 | Explanation: The array cannot be partitioned into equal sum subsets. 32 | ``` 33 | 34 | ## 解题方案 35 | 36 | > 思路 1 37 | 38 | 动态规划 39 | 40 | dp[i]代表nums中能否找出一个subset的sum等于i,例如dp[0] = True是必然的,因为我们只要取空子集,那么其sum一定为0 41 | 42 | ```python 43 | class Solution(object): 44 | def canPartition(self, nums): 45 | """ 46 | :type nums: List[int] 47 | :rtype: bool 48 | """ 49 | if not nums or len(nums) == 0: 50 | return True 51 | if sum(nums) % 2 != 0: ## 总和必须为偶数,否则肯定无法取两个集合的sum相等 52 | return False 53 | half_sum = sum(nums)/2 54 | dp = [False] * (half_sum+1) 55 | dp[0] = True 56 | for i in range(len(nums)): 57 | for j in range(half_sum, nums[i]-1, -1): 58 | dp[j] = dp[j] or dp[j-nums[i]] 59 | print(dp) 60 | return dp[half_sum] 61 | ``` 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /251-500/422. Valid Word Square.md: -------------------------------------------------------------------------------- 1 | ### 422. Valid Word Square 2 | 3 | 4 | 5 | 6 | 7 | 题目: 8 | 9 | 10 | 11 | 12 | 难度 : Easy 13 | 14 | 15 | 16 | 思路: 17 | 18 | 就是对比一个矩阵内 xy == yx? 19 | 20 | try /except 真是好用 21 | 22 | AC代码 23 | 24 | 25 | 26 | ``` 27 | class Solution(object): 28 | def validWordSquare(self, words): 29 | """ 30 | :type words: List[str] 31 | :rtype: bool 32 | """ 33 | n = len(words) 34 | for i in xrange(n): 35 | m = len(words[i]) 36 | for j in xrange(m): 37 | try: 38 | if words[i][j] != words[j][i]: 39 | return False 40 | except: 41 | return False 42 | return True 43 | ``` 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /251-500/434._number_of_segments_in_a_string.md: -------------------------------------------------------------------------------- 1 | ### 434. Number of Segments in a String 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 作弊神器Python 13 | 14 | 15 | ```python 16 | class Solution(object): 17 | def countSegments(self, s): 18 | """ 19 | :type s: str 20 | :rtype: int 21 | """ 22 | return len(s.split()) 23 | ``` 24 | 25 | 不过对于比如C++这种语言来说,应该是O(N),扫一圈应该也能得到正确答案 26 | 27 | 总之拿Python做string的题目就是作弊啊 28 | -------------------------------------------------------------------------------- /251-500/439. Ternary Expression Parser.md: -------------------------------------------------------------------------------- 1 | ### 439. Ternary Expression Parser 2 | 3 | 4 | 5 | 6 | 7 | 题目: 8 | 9 | 10 | 11 | 12 | 难度: 13 | Medium 14 | 15 | 思路: 16 | 17 | 其实这个和算术运算蛮像,但是不同于运算,有operator precedence差别,这个是三目运算,并且需要检查是否符合运算规则。 18 | 19 | 20 | 21 | 运用stack 然后每次查看是否形成运算式再来做处理 22 | 23 | AC代码: 24 | 25 | ``` 26 | class Solution(object): 27 | def parseTernary(self, expression): 28 | """ 29 | :type expression: str 30 | :rtype: str 31 | """ 32 | n = len(expression) 33 | 34 | stack = [] 35 | 36 | for i in range(n-1, -1, -1): 37 | char = expression[i] 38 | stack.append(char) 39 | 40 | if len(stack) >= 5: 41 | op0 = stack.pop() 42 | op1 = stack.pop() 43 | op2 = stack.pop() 44 | op3 = stack.pop() 45 | op4 = stack.pop() 46 | 47 | if op1 == '?' and op3 == ':': 48 | res = op2 if op0 == 'T' else op4 49 | stack.append(res) 50 | else: 51 | stack.append(op4) 52 | stack.append(op3) 53 | stack.append(op2) 54 | stack.append(op1) 55 | stack.append(op0) 56 | return stack[0] 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /251-500/441._arranging_coins.md: -------------------------------------------------------------------------------- 1 | ###441. Arranging Coins 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Easy 9 | 10 | 11 | 可以直接O(1),公式: 12 | 13 | i(i+1)/2 = n 14 | 15 | 解i 16 | 17 | i = ( sqrt(8*n+1) -1 )/ 2 18 | 19 | 20 | ``` 21 | import math 22 | class Solution(object): 23 | def arrangeCoins(self, n): 24 | """ 25 | :type n: int 26 | :rtype: int 27 | """ 28 | return int((math.sqrt( 8 * n + 1) - 1 )/ 2 ) 29 | ``` -------------------------------------------------------------------------------- /251-500/448._Find_All_Numbers_Disappeared_in_an_Array.md: -------------------------------------------------------------------------------- 1 | ### 448. Find All Numbers Disappeared in an Array 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 13 | 14 | 15 | ```python 16 | class Solution(object): 17 | def findDisappearedNumbers(self, nums): 18 | """ 19 | :type nums: List[int] 20 | :rtype: List[int] 21 | """ 22 | return list(set(range(1, len(nums)+1)) - set(nums)) 23 | ``` 24 | 25 | 26 | -------------------------------------------------------------------------------- /251-500/459._Repeated_Substring_Pattern.md: -------------------------------------------------------------------------------- 1 | ### 459. Repeated Substring Pattern 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 思路 14 | 15 | - 如果存在这样的子串,那么子串的第一个字符和最后一个字符肯定跟父字符串```s```的相同。 16 | - 因此构建一个新字符串```s*2```(两个父字符串相加),去掉首尾字符 17 | - 如果此时能在其中找到```s```,说明存在这样的子串 18 | 19 | 20 | 21 | 22 | ```python 23 | class Solution(object): 24 | def repeatedSubstringPattern(self, s): 25 | """ 26 | :type s: str 27 | :rtype: bool 28 | """ 29 | return (s*2)[1:-1].find(s) != -1 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /251-500/467._Unique_Substrings_in_Wraparound_String.md: -------------------------------------------------------------------------------- 1 | ### 467. Unique Substrings in Wraparound String 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Medium 10 | 11 | 12 | 思路: 13 | 14 | 有个无限长的字符串s,是由无数个「abcdefghijklmnopqrstuvwxyz」组成的。现在给你一个字符串p,求多少个p的非空子串在s中出现了? 15 |    16 | 17 | 先考虑s的特性,满足条件(在s中)的p的子串只可能是abcd……z的连续序列(z后面是a), 我们只需要处理p中连续的部分就可以了。但是 举个例子,h-k的序列出现了,a-z的序列也出现了,那么只需要计算a-z的子串个数就可以了,因为h-k已经包含在a-z里了。考虑所有包含的情况,似乎就变得复杂了,a-z还可能被包含在x-za-z中,甚至更长的序列中。 18 | 19 |   但是如果考虑以某个字母结尾的子串个数,那么p中以该字母结尾的连续序列长度,就是满足条件的子串个数。如果以字母x结尾的连续序列有多个, 我们只需要最长的一个即可,因为其他短的序列都已经被长的包含进去了,例如'bcd'和'abcd',有了'abcd'就知道以d结尾的子串有4个,分别是‘d’,'cd','bcd','abcd',‘bcd’已经被包含进去了。最后求和,问题就解决了。 这样思考就非常简单了,代码也可以很容易写出来。 20 | 21 | 22 | 23 | ```python 24 | class Solution(object): 25 | def findSubstringInWraproundString(self, p): 26 | """ 27 | :type p: str 28 | :rtype: int 29 | """ 30 |        letters = [0] * 26         #开始默认每个都是0 31 |        length = 0 32 | for i in range(len(p)): 33 | curr = ord(p[i]) - ord('a') 34 |            if i > 0 and ord(p[i-1]) != (curr-1)%26 + ord('a'):   #一旦开始不相等了就要将length重置为0 35 |                length = 0 36 |            length += 1     #否则就说明继续与前面一个字符是连续的,length要加1才行 37 |            if length > letters[curr]:     #length一直加,如果到i这个字符length比它的目前的最大连续子串长度还要长,那么肯定要更新letters 38 |                letters[curr] = length 39 | return sum(letters) 40 | ``` 41 | 42 | 43 | -------------------------------------------------------------------------------- /251-500/476._Number_Complement.md: -------------------------------------------------------------------------------- 1 | ### 476. Number Complement 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 13 | 14 | 15 | 16 | ```python 17 | class Solution(object): 18 | def findComplement(self, num): 19 | """ 20 | :type num: int 21 | :rtype: int 22 | """ 23 | i = 1 << (len(bin(num)) -2) # 因为bin函数转化成的格式是‘0bXXXX’,头两个‘0b’要减掉去 24 | return (i - 1) ^ num 25 | # return (i - 1) - num # 这样也可以 26 | ``` 27 | 28 | 29 | -------------------------------------------------------------------------------- /251-500/485._Max_Consecutive_Ones.md: -------------------------------------------------------------------------------- 1 | # 485. Max Consecutive Ones 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/max-consecutive-ones/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a binary array, find the maximum number of consecutive 1s in this array. 15 | 16 | Example 1: 17 | Input: [1,1,0,1,1,1] 18 | Output: 3 19 | Explanation: The first two digits or the last three digits are consecutive 1s. 20 | The maximum number of consecutive 1s is 3. 21 | Note: 22 | 23 | The input array will only contain 0 and 1. 24 | The length of input array is a positive integer and will not exceed 10,000 25 | ``` 26 | 27 | ## 解题方案 28 | 29 | > 思路 1 30 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 31 | 32 | 33 | 一行无敌 34 | ```python 35 | class Solution(object): 36 | def findMaxConsecutiveOnes(self, nums): 37 | """ 38 | :type nums: List[int] 39 | :rtype: int 40 | """ 41 | return len(max(''.join(map(str, nums)).split('0'))) 42 | ``` 43 | 44 | 45 | > 思路 2 46 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 47 | 48 | ```python 49 | class Solution(object): 50 | def findMaxConsecutiveOnes(self, nums): 51 | """ 52 | :type nums: List[int] 53 | :rtype: int 54 | """ 55 | res, count = [], 0 56 | for x in nums: 57 | count = 0 if x == 0 else count + 1 58 | res.append(count) 59 | return max(res) 60 | ``` 61 | 62 | 63 | -------------------------------------------------------------------------------- /501-750/507._Perfect_Number.md: -------------------------------------------------------------------------------- 1 | # 507. Perfect Number 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/perfect-number/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | We define the Perfect Number is a positive integer that is equal to the sum of all its positive divisors except itself. 15 | 16 | Now, given an integer n, write a function that returns true when it is a perfect number and false when it is not. 17 | Example: 18 | Input: 28 19 | Output: True 20 | Explanation: 28 = 1 + 2 + 4 + 7 + 14 21 | Note: The input number n will not exceed 100,000,000. (1e8) 22 | ``` 23 | 24 | ## 解题方案 25 | 26 | > 思路 1 27 | ******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)****** 28 | 29 | 用了一个比较巧妙的方法,首先排除一些 corner case,num 小于等于1的时候直接返回 False 30 | 31 | 然后后面开始这个方法,就是我们其实不需要对所有小于 num 的数字做遍历,只需要从 2 遍历到 int(sqrt(num)) 即可, 32 | 然后每次可以整除的时候都加上当前数字 i 和 num//i,然后初始化的时候让 sums = 1 ,这样最后就是不包含自己的所有因子的和,最后 return sum == num 33 | 34 | 35 | beats 95.73% 36 | ```python 37 | from math import sqrt 38 | class Solution(object): 39 | def checkPerfectNumber(self, num): 40 | """ 41 | :type num: int 42 | :rtype: bool 43 | """ 44 | if num <= 1: 45 | return False 46 | sums = 1 47 | for i in range(2, int(sqrt(num))+1): 48 | if num % i == 0: 49 | sums += i + num // i 50 | return sums == num 51 | ``` 52 | -------------------------------------------------------------------------------- /501-750/539._Minimum_Time_Difference.md: -------------------------------------------------------------------------------- 1 | # 539. Minimum Time Difference 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/minimum-time-difference/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minutes difference between any two time points in the list. 15 | Example 1: 16 | Input: ["23:59","00:00"] 17 | Output: 1 18 | Note: 19 | The number of time points in the given list is at least 2 and won't exceed 20000. 20 | The input time is legal and ranges from 00:00 to 23:59. 21 | ``` 22 | 23 | ## 解题方案 24 | 25 | > 思路 1 26 | ******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)****** 27 | 28 | 先全部转换成分钟数,再排序,然后取最小差值,唯一要注意首尾两者差值可能还最小,例如["23:59","00:00"] 29 | 30 | ```python 31 | class Solution(object): 32 | def findMinDifference(self, timePoints): 33 | """ 34 | :type timePoints: List[str] 35 | :rtype: int 36 | """ 37 | tp = sorted(60*int(pt[:2])+int(pt[3:]) for pt in timePoints) 38 | return min(min(b - a for (a, b) in zip(tp, tp[1:])), (24*60)+tp[0]-tp[-1]) 39 | ``` 40 | -------------------------------------------------------------------------------- /501-750/560._Subarray_Sum_Equals_K.md: -------------------------------------------------------------------------------- 1 | # 560. Subarray Sum Equals K 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/subarray-sum-equals-k/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. 15 | 16 | Example 1: 17 | Input:nums = [1,1,1], k = 2 18 | Output: 2 19 | Note: 20 | The length of the array is in range [1, 20,000]. 21 | The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. 22 | ``` 23 | 24 | ## 解题方案 25 | 26 | > 思路 1 27 | 28 | 29 | 跟two sum一样的题目 30 | 31 | 就不停维护一个当前和的变量,然后每次都check一下```当前和 - k```是否在字典里面,如果存在我们就知道了之前有一坨字符串和的值为```当前和 - k```,然后 32 | 当前和的值就是当前和,所以最近接触的一坨字符串其和必为k 33 | 34 | 例如在[1,2,3,4]里面找7,之前存过1+2在字典里面,然后循环到4的时候当前和为10,就看看3在不在字典里面,一看果然有,那么最近一坨的 3+4 = 7,找到了 35 | 36 | 但是这里要注意光找到没用,我们要知道存在多少个,所以字典里面的value对应的就是当前和出现的次数 37 | 38 | AC 代码: 39 | 40 | ```python 41 | class Solution(object): 42 | def subarraySum(self, nums, k): 43 | """ 44 | :type nums: List[int] 45 | :type k: int 46 | :rtype: int 47 | """ 48 | # 这是为了保证如果当前和的值就等于k的话,我们其实也相当于找到一次 49 | lookup = {0:1} 50 | res = cur_sum = 0 51 | for num in nums: 52 | cur_sum += num 53 | res += lookup.get(cur_sum-k, 0) 54 | lookup[cur_sum] = lookup.get(cur_sum, 0) + 1 55 | return res 56 | ``` 57 | -------------------------------------------------------------------------------- /501-750/595._Big_Countries.md: -------------------------------------------------------------------------------- 1 | # 595. Big Countries 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/big-countries/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | There is a table World 15 | 16 | +-----------------+------------+------------+--------------+---------------+ 17 | | name | continent | area | population | gdp | 18 | +-----------------+------------+------------+--------------+---------------+ 19 | | Afghanistan | Asia | 652230 | 25500100 | 20343000 | 20 | | Albania | Europe | 28748 | 2831741 | 12960000 | 21 | | Algeria | Africa | 2381741 | 37100000 | 188681000 | 22 | | Andorra | Europe | 468 | 78115 | 3712000 | 23 | | Angola | Africa | 1246700 | 20609294 | 100990000 | 24 | +-----------------+------------+------------+--------------+---------------+ 25 | A country is big if it has an area of bigger than 3 million square km or a population of more than 25 million. 26 | 27 | Write a SQL solution to output big countries' name, population and area. 28 | 29 | For example, according to the above table, we should output: 30 | 31 | +--------------+-------------+--------------+ 32 | | name | population | area | 33 | +--------------+-------------+--------------+ 34 | | Afghanistan | 25500100 | 652230 | 35 | | Algeria | 37100000 | 2381741 | 36 | +--------------+-------------+--------------+ 37 | ``` 38 | 39 | ## 解题方案 40 | 41 | > 思路 1 42 | 43 | ```sql 44 | select name, population, area from World where area > 3000000 or population > 25000000; 45 | ``` 46 | -------------------------------------------------------------------------------- /501-750/599._Minimum_Index_Sum_of_Two_Lists.md: -------------------------------------------------------------------------------- 1 | ### 599. Minimum Index Sum of Two Lists 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 14 | 思路 15 | 16 | 两个list,我们首先要取得它们相同的部分,并且之后我们还要知道哪个相同的字符串在两个list中的index之和是最小的。 17 | - 所以我们首先遍历list1,只要目前这个字符串在list2中,我们就以[字符串,index之和]的形式将其存放到ress中,同时维护一个index保持为最小index之和的值 18 | - 对于ress,我们遍历,只要某一项的index之和等于最小index之和我们就将他的字符串以i[0]的形式append到res中去, 19 | - return res 20 | 21 | ### 程序变量解释 22 | 23 | - ress format: [[string1, sumOfIndex1], [string2, sumOfIndex2]... ] 24 | - index 最小sunOfIndex值 25 | - res 最终结果,foramt: [string1, string2,. ...] 26 | 27 | 28 | 29 | 30 | ```python 31 | python 32 | class Solution: 33 | def findRestaurant(self, list1, list2): 34 | """ 35 | :type list1: List[str] 36 | :type list2: List[str] 37 | :rtype: List[str] 38 | """ 39 | ress = [] 40 | index = 2000 41 | for i in list1: 42 | if i in list2: 43 | ress.append([i, list1.index(i)+list2.index(i)]) 44 | index = min(index, list1.index(i)+list2.index(i)) 45 | res = [] 46 | for i in ress: 47 | if i[1] == index: 48 | res.append(i[0]) 49 | return res 50 | ``` 51 | 52 | 53 | 54 | Author: Keqi Huang 55 | 56 | If you like it, please spread your support 57 | 58 | ![Support](https://github.com/Lisanaaa/myTODOs/blob/master/WechatIMG17.jpeg) 59 | -------------------------------------------------------------------------------- /501-750/613._Shortest_Distance_in_a_Line.md: -------------------------------------------------------------------------------- 1 | # 613. Shortest Distance in a Line 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/shortest-distance-in-a-line/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Table point holds the x coordinate of some points on x-axis in a plane, which are all integers. 15 | Write a query to find the shortest distance between two points in these points. 16 | | x | 17 | |-----| 18 | | -1 | 19 | | 0 | 20 | | 2 | 21 | The shortest distance is '1' obviously, which is from point '-1' to '0'. So the output is as below: 22 | | shortest| 23 | |---------| 24 | | 1 | 25 | Note: Every point is unique, which means there is no duplicates in table point. 26 | Follow-up: What if all these points have an id and are arranged from the left most to the right most of x axis? 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | 33 | ```sql 34 | select min(abs(p1.x-p2.x)) as shortest from point p1, point p2 where p1.x != p2.x; 35 | ``` 36 | 37 | > 思路 2 38 | 39 | ```sql 40 | select min(p2.x-p1.x) shortest from point p1 inner join point p2 where p2.x > p1.x; 41 | ``` 42 | -------------------------------------------------------------------------------- /501-750/653._Two_Sum_IV_-_Input_is_a_BST.md: -------------------------------------------------------------------------------- 1 | # 653. Two Sum IV - Input is a BST 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target. 15 | 16 | Example 1: 17 | Input: 18 | 5 19 | / \ 20 | 3 6 21 | / \ \ 22 | 2 4 7 23 | 24 | Target = 9 25 | 26 | Output: True 27 | Example 2: 28 | Input: 29 | 5 30 | / \ 31 | 3 6 32 | / \ \ 33 | 2 4 7 34 | 35 | Target = 28 36 | 37 | Output: False 38 | ``` 39 | 40 | ## 解题方案 41 | 42 | > 思路 1 43 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 44 | 45 | 46 | inorder遍历是O(N),后面的二分是O(lgN),总的时间复杂度为O(N) 47 | 48 | beats 75.90% 49 | 50 | ```python 51 | class Solution(object): 52 | def findTarget(self, root, k): 53 | """ 54 | :type root: TreeNode 55 | :type k: int 56 | :rtype: bool 57 | """ 58 | def inorder(root): 59 | if not root: 60 | return 61 | inorder(root.left) 62 | nums.append(root.val) 63 | inorder(root.right) 64 | 65 | nums = [] 66 | inorder(root) 67 | l, r = 0, len(nums) - 1 68 | while l < r: 69 | if nums[l] + nums[r] == k: 70 | return True 71 | elif nums[l] + nums[r] < k: 72 | l += 1 73 | else: 74 | r -= 1 75 | return False 76 | ``` 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /501-750/657._Judge_Route_Circle.md: -------------------------------------------------------------------------------- 1 | ### 657. Judge Route Circle 2 | 题目: 3 | 4 | 5 | 6 | 难度: 7 | 8 | Easy 9 | 10 | 11 | 12 | 13 | ```python 14 | class Solution(object): 15 | def judgeCircle(self, moves): 16 | """ 17 | :type moves: str 18 | :rtype: bool 19 | """ 20 | return moves.count('D') == moves.count('U') and moves.count('R') == moves.count('L') 21 | ``` 22 | 23 | 24 | -------------------------------------------------------------------------------- /501-750/681._Next_Closest_Time.md: -------------------------------------------------------------------------------- 1 | ### 681. Next Closest Time 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 13 | 14 | 思路 15 | 16 | 题目说输入一个时间,format是HH:MM, 然后输出接下来最近的一个时间,且这个时间的数字必须要在输入的时间中可以找到,所以我们用```h```, ```m``` 17 | 分别代表输入时间的小时数和分钟数,然后可以计算出输入时间的总分钟数```curr```,在未来的一天之内,我们一分钟一分钟往下面试,第一个满足的就直接 18 | 作为结果就行了. 19 | 20 | 21 | 22 | 23 | ```python 24 | class Solution(object): 25 | def nextClosestTime(self, time): 26 | """ 27 | :type time: str 28 | :rtype: str 29 | """ 30 | h, m = time.split(":") 31 |        curr = int(h) * 60 + int(m) # 这里要注意h可能会是0开头的,如输入的时间为01:22,所以需要int(h)和int(m) 32 |        result = None 33 | for i in xrange(curr+1, curr+1441): 34 | t = i % 1440 35 | h, m = t // 60, t % 60 36 | result = "%02d:%02d" % (h, m) 37 | if set(result) <= set(time): 38 | break 39 | return result 40 | ``` 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /501-750/682._Baseball_Game.md: -------------------------------------------------------------------------------- 1 | ### 682. Baseball Game 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路 13 | 14 | points用来存放每一次的分数,最后求和。 15 | 16 | 17 | ```python 18 | class Solution(object): 19 | def calPoints(self, ops): 20 | """ 21 | :type ops: List[str] 22 | :rtype: int 23 | """ 24 | points = [] 25 | for i in ops: 26 | if i == 'C': 27 | points.pop() 28 | elif i == 'D': 29 | points.append(2 * points[-1]) 30 | elif i == '+': 31 | points.append(points[-1] + points[-2]) 32 | else: 33 | points.append(int(i)) 34 | return sum(points) 35 | ``` 36 | 37 | 38 | -------------------------------------------------------------------------------- /501-750/693._Binary_Number_with_Alternating_Bits.md: -------------------------------------------------------------------------------- 1 | # 693. Binary Number with Alternating Bits 交替位二进制数 2 | 3 | **难度: 中等** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/binary-number-with-alternating-bits/description/ 10 | * https://leetcode-cn.com/problems/binary-number-with-alternating-bits/description/ 11 | 12 | > 内容描述 13 | 14 | ``` 15 | 给定一个正整数,检查他是否为交替位二进制数:换句话说,就是他的二进制数相邻的两个位数永不相等。 16 | 17 | 示例 1: 18 | 19 | 输入: 5 20 | 输出: True 21 | 解释: 22 | 5的二进制数是: 101 23 | 示例 2: 24 | 25 | 输入: 7 26 | 输出: False 27 | 解释: 28 | 7的二进制数是: 111 29 | 示例 3: 30 | 31 | 输入: 11 32 | 输出: False 33 | 解释: 34 | 11的二进制数是: 1011 35 | 示例 4: 36 | 37 | 输入: 10 38 | 输出: True 39 | 解释: 40 | 10的二进制数是: 1010 41 | ``` 42 | 43 | ## 解题方案 44 | 45 | > 思路 1 46 | 47 | 太简单了,可以一行秒,但是太难看了,还是多写几行吧 48 | 49 | 调用bin函数转换成二进制以后再转换成字符串,注意二进制前面2为是‘0b’,要记得去掉 50 | 51 | ```python 52 | class Solution(object): 53 | def hasAlternatingBits(self, n): 54 | """ 55 | :type n: int 56 | :rtype: bool 57 | """ 58 | tmp = str(bin(n))[2:] 59 | res = [tmp[i] != tmp[i-1] for i in range(1, len(tmp))] 60 | return all(res) 61 | ``` 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /751-920/760._Find_Anagram_Mappings.md: -------------------------------------------------------------------------------- 1 | ### 760. Find Anagram Mappings 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 13 | 14 | 15 | ```python 16 | class Solution(object): 17 | def anagramMappings(self, A, B): 18 | """ 19 | :type A: List[int] 20 | :type B: List[int] 21 | :rtype: List[int] 22 | """ 23 | if not A: 24 | return [] 25 | res = [] 26 | for i in A: 27 | res.append(B.index(i)) 28 | return res 29 | ``` 30 | 31 | 32 | -------------------------------------------------------------------------------- /751-920/796._Rotate_String.md: -------------------------------------------------------------------------------- 1 | # 796. Rotate String 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/rotate-string/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | We are given two strings, A and B. 15 | 16 | A shift on A consists of taking string A and moving the leftmost character to the rightmost position. For example, if A = 'abcde', then it will be 'bcdea' after one shift on A. Return True if and only if A can become B after some number of shifts on A. 17 | 18 | Example 1: 19 | Input: A = 'abcde', B = 'cdeab' 20 | Output: true 21 | 22 | Example 2: 23 | Input: A = 'abcde', B = 'abced' 24 | Output: false 25 | Note: 26 | 27 | A and B will have length at most 100. 28 | ``` 29 | 30 | ## 解题方案 31 | 32 | > 思路 1 33 | 34 | 35 | 一行就够了,太简单了 36 | 37 | ```python 38 | class Solution(object): 39 | def rotateString(self, A, B): 40 | """ 41 | :type A: str 42 | :type B: str 43 | :rtype: bool 44 | """ 45 | return len(A) == len(B) and B in A * 2 46 | ``` 47 | -------------------------------------------------------------------------------- /751-920/905._Sort_Array_By_Parity.md: -------------------------------------------------------------------------------- 1 | # 905. Sort Array By Parity 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/sort-array-by-parity/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an array A of non-negative integers, return an array consisting of all the even elements of A, followed by all the odd elements of A. 15 | 16 | You may return any answer array that satisfies this condition. 17 | 18 | 19 | 20 | Example 1: 21 | 22 | Input: [3,1,2,4] 23 | Output: [2,4,3,1] 24 | The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted. 25 | 26 | 27 | Note: 28 | 29 | 1 <= A.length <= 5000 30 | 0 <= A[i] <= 5000 31 | ``` 32 | 33 | ## 解题方案 34 | 35 | > 思路 1 36 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 37 | 38 | 贼暴力思路 39 | 40 | ```python 41 | class Solution(object): 42 | def sortArrayByParity(self, A): 43 | """ 44 | :type A: List[int] 45 | :rtype: List[int] 46 | """ 47 | return [i for i in A if i & 1 == 0] + [i for i in A if i & 1 == 1] 48 | ``` 49 | 50 | 51 | 52 | 53 | > 思路 2 54 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 55 | 56 | 57 | 优化空间,in-place AC! 58 | 59 | ```python 60 | class Solution(object): 61 | def sortArrayByParity(self, A): 62 | """ 63 | :type A: List[int] 64 | :rtype: List[int] 65 | """ 66 | idx = 0 # idx 指向的永远是奇数的 candidate 67 | for i in range(len(A)): 68 | if A[i] & 1 == 0: 69 | A[i], A[idx] = A[idx], A[i] 70 | idx += 1 71 | return A 72 | ``` 73 | -------------------------------------------------------------------------------- /751-920/908._Smallest_Range.md: -------------------------------------------------------------------------------- 1 | # 908. Smallest Range 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/smallest-range-i/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K, and add x to A[i]. 15 | 16 | After this process, we have some array B. 17 | 18 | Return the smallest possible difference between the maximum value of B and the minimum value of B. 19 | 20 | 21 | 22 | Example 1: 23 | 24 | Input: A = [1], K = 0 25 | Output: 0 26 | Explanation: B = [1] 27 | Example 2: 28 | 29 | Input: A = [0,10], K = 2 30 | Output: 6 31 | Explanation: B = [2,8] 32 | Example 3: 33 | 34 | Input: A = [1,3,6], K = 3 35 | Output: 0 36 | Explanation: B = [3,3,3] or B = [4,4,4] 37 | 38 | 39 | Note: 40 | 41 | 1 <= A.length <= 10000 42 | 0 <= A[i] <= 10000 43 | 0 <= K <= 10000 44 | ``` 45 | 46 | ## 解题方案 47 | 48 | > 思路 1 49 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 50 | 51 | 比赛起晚了,9点25惊醒,看到题目后 3 分钟多一点 bug free 一遍 AC 52 | 53 | 这个题目这么简单就没必要说什么了 54 | 55 | 56 | ```python 57 | class Solution(object): 58 | def smallestRangeI(self, A, K): 59 | """ 60 | :type A: List[int] 61 | :type K: int 62 | :rtype: int 63 | """ 64 | max_num = max(A) 65 | min_num = min(A) 66 | if max_num - min_num > 2 * abs(K): 67 | return max_num - min_num - 2 * abs(K) 68 | elif max_num - min_num <= 2 * abs(K): 69 | return 0 70 | ``` 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /751-920/917._Reverse_Only_Letters.md: -------------------------------------------------------------------------------- 1 | # 917. Reverse Only Letters 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/contest/weekly-contest-105/problems/reverse-only-letters/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a string S, return the "reversed" string where all characters that are not a letter stay in the same place, and all letters reverse their positions. 15 | 16 | 17 | 18 | Example 1: 19 | 20 | Input: "ab-cd" 21 | Output: "dc-ba" 22 | Example 2: 23 | 24 | Input: "a-bC-dEf-ghIj" 25 | Output: "j-Ih-gfE-dCba" 26 | Example 3: 27 | 28 | Input: "Test1ng-Leet=code-Q!" 29 | Output: "Qedo1ct-eeLg=ntse-T!" 30 | 31 | 32 | Note: 33 | 34 | S.length <= 100 35 | 33 <= S[i].ASCIIcode <= 122 36 | S doesn't contain \ or " 37 | ``` 38 | 39 | ## 解题方案 40 | 41 | > 思路 1 42 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 43 | 44 | sb题没什么好说的 45 | 46 | 47 | ```python 48 | class Solution(object): 49 | def reverseOnlyLetters(self, S): 50 | """ 51 | :type S: str 52 | :rtype: str 53 | """ 54 | if not S or len(S) == 0: 55 | return '' 56 | tmp = [] 57 | res = [] 58 | for c in S: 59 | if 'a' <= c <= 'z' or 'A' <= c <= 'Z': 60 | tmp.append(c) 61 | res.append(c) 62 | tmp = tmp[::-1] 63 | idx = 0 64 | for i, c in enumerate(res): 65 | if 'a' <= c <= 'z' or 'A' <= c <= 'Z': 66 | res[i] = tmp[idx] 67 | idx += 1 68 | return ''.join(res) 69 | ``` 70 | 71 | 72 | -------------------------------------------------------------------------------- /Backtracking/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Backtracking/.DS_Store -------------------------------------------------------------------------------- /Backtracking/read/039._combination_sum.md: -------------------------------------------------------------------------------- 1 | ### 39. Combination Sum 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 13 | 最初的思路: 14 | 15 | 16 | ``` 17 | res = [] 18 | def combSum(candidates, target, valueList): 19 | if target == 0: 20 | res.append(valueList) 21 | for candidate in candidates: 22 | if candidate > target: 23 | return 24 | combSum(candidates, target - candidate, valueList + [candidate] ) 25 | 26 | ``` 27 | 28 | 29 | 问题在于,有重复: 30 | 31 | ``` 32 | combSum([2,3,6,7],7,[]) 33 | 34 | res 35 | Out[9]: [[2, 2, 3], [2, 3, 2], [3, 2, 2], [7]] 36 | ``` 37 | 38 | 然后看了hint,除[2, 2, 3] 和 [2, 3, 2]这种重复的方式是, 把candidates先sort,然后用index的方式来处理。 39 | 40 | 41 | 所以最终的除重大法如下,根据hint做出: 42 | 43 | ```python 44 | class Solution(object): 45 | def combinationSum(self, candidates, target): 46 | """ 47 | :type candidates: List[int] 48 | :type target: int 49 | :rtype: List[List[int]] 50 | """ 51 | def dfs(remain, combo, index): 52 | if remain == 0: 53 | res.append(combo) 54 | return 55 | for i in range(index, len(candidates)): 56 | if candidates[i] > remain: 57 | break 58 | dfs(remain - candidates[i], combo + [candidates[i]], i) 59 | candidates = list(set(candidates)) 60 | candidates.sort() 61 | res = [] 62 | dfs(target, [], 0) 63 | return res 64 | ``` 65 | -------------------------------------------------------------------------------- /Backtracking/read/040._combination_sum_ii.md: -------------------------------------------------------------------------------- 1 | ### 40. Combination Sum II 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 13 | Combination Sum 已经AC,做了minor change. 14 | - 现在不需要```set```化```candidates```了 15 | - 但是递归的时候```index```要从```i+1```开始了 16 | - 要判断```combo not in res```才```append```到```res```中去 17 | 18 | ```python 19 | class Solution(object): 20 | def combinationSum2(self, candidates, target): 21 | """ 22 | :type candidates: List[int] 23 | :type target: int 24 | :rtype: List[List[int]] 25 | """ 26 | def dfs(remain, combo, index): 27 | if remain == 0 and combo not in res: 28 | res.append(combo) 29 | return 30 | for i in range(index, len(candidates)): 31 | if candidates[i] > remain: 32 | break 33 | dfs(remain - candidates[i], combo + [candidates[i]], i+1) 34 | candidates.sort() 35 | res = [] 36 | dfs(target, [], 0) 37 | return res 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /Backtracking/read/046._permutations.md: -------------------------------------------------------------------------------- 1 | # 46. Permutations 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/permutations/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a collection of distinct integers, return all possible permutations. 15 | 16 | Example: 17 | 18 | Input: [1,2,3] 19 | Output: 20 | [ 21 | [1,2,3], 22 | [1,3,2], 23 | [2,1,3], 24 | [2,3,1], 25 | [3,1,2], 26 | [3,2,1] 27 | ] 28 | ``` 29 | 30 | ## 解题方案 31 | 32 | > 思路 1 33 | ******- 时间复杂度: O(N!)******- 空间复杂度: O(N)****** 34 | 35 | 36 | 每次取一个作为prefix, 剩下的继续做permutation,然后连接起来加入res中 37 | 38 | beats 87.18% 39 | 40 | ```python 41 | class Solution(object): 42 | def permute(self, nums): 43 | """ 44 | :type nums: List[int] 45 | :rtype: List[List[int]] 46 | """ 47 | if len(nums) == 0: 48 | return [] 49 | if len(nums) == 1: 50 | return [nums] 51 | res = [] 52 | for i in range(len(nums)): 53 | prefix = nums[i] 54 | rest = nums[:i] + nums[i+1:] 55 | for j in self.permute(rest): 56 | res.append([prefix]+j) 57 | return res 58 | ``` 59 | 60 | 61 | -------------------------------------------------------------------------------- /Backtracking/read/047._permutations_ii.md: -------------------------------------------------------------------------------- 1 | ### 47. Permutations II 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Medium 10 | 11 | 跟第46题一样,就是最后append的时候不一样,只有没有结果里面没有的才加入 12 | 13 | 14 | ```python 15 | class Solution(object): 16 | def permuteUnique(self, nums): 17 | """ 18 | :type nums: List[int] 19 | :rtype: List[List[int]] 20 | """ 21 | if len(nums) == 0: 22 | return [] 23 | if len(nums) == 1: 24 | return [nums] 25 | res = [] 26 | for i in range(len(nums)): 27 | prefix = nums[i] 28 | rest = nums[:i] + nums[i+1:] 29 | for j in self.permuteUnique(rest): 30 | if [prefix]+j not in res: 31 | res.append([prefix]+j) 32 | return res 33 | ``` 34 | 35 | 36 | -------------------------------------------------------------------------------- /Backtracking/read/052._n-queens_ii.md: -------------------------------------------------------------------------------- 1 | ### 52. N-Queens II 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Hard 9 | 10 | 思路参见recursion & backtracking 11 | 12 | n queens还是属于比较难的,需要花时间吃透的问题 13 | 14 | 八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当n = 1或n ≥ 4时问题有解[1]。 15 | 16 | 对于任意(x,y),如果要让新的点和它不能处于同一条横行、纵行或斜线上,则新点(p,q)必须要满足p+q != x+y 和p-q!= x-y, 前者针对左下右上斜线,后者针对左上右下斜线,两者同时都保证了不在同一条横行和纵行上。 17 | 18 | 代码中变量的含义: 19 | - col_per_row: 每一行皇后的column位置组成的列表 20 | - cur_row:目前正在判断的row的index 21 | - xy_diff:所有x-y组成的列表 22 | - xy_sum:所有x+y组成的列表 23 | 24 | ```python 25 | class Solution(object): 26 | def totalNQueens(self, n): 27 | """ 28 | :type n: int 29 | :rtype: int 30 | """ 31 | def dfs(col_per_row, xy_diff, xy_sum): 32 | cur_row = len(col_per_row) 33 | if cur_row == n: 34 | ress.append(col_per_row) 35 | for col in range(n): 36 | if col not in col_per_row and cur_row-col not in xy_diff and cur_row+col not in xy_sum: 37 | dfs(col_per_row+[col], xy_diff+[cur_row-col], xy_sum+[cur_row+col]) 38 | ress = [] 39 | dfs([], [], []) 40 | return len(ress) 41 | 42 | ``` 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Backtracking/read/077._combinations.md: -------------------------------------------------------------------------------- 1 | ###77. Combinations 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度 : Medium 9 | 10 | 11 | 解法三: 12 | 13 | 14 | 采用递归的方式,在n个数中选k个,如果n大于k,那么可以分类讨论,如果选了n,那么就是在1到(n-1)中选(k-1)个,否则就是在1到(n-1)中选k个。递归终止的条件是k为1,这时候1到n都符合要求。 15 | 16 | 注意一开始这里的else part花了我一点时间来理解,因为n必定大于k,所以这样递归当 n == k的时候选法就是code原作者的写法,也就是直接[range(1,k+1)] 17 | 18 | 参考这里: 19 | 20 | 21 | ``` 22 | class Solution(object): 23 | def combine(self, n, k): 24 | """ 25 | :type n: int 26 | :type k: int 27 | :rtype: List[List[int]] 28 | """ 29 | if k == 1: 30 | return [[i + 1] for i in range(n)] 31 | result = [] 32 | if n > k: 33 | result = [r + [n] for r in self.combine(n - 1, k - 1)] + self.combine(n - 1, k) 34 | else: #n == k 35 | # result = [r + [n] for r in self.combine(n - 1, k - 1)] 36 | result = [range(1,k+1)] 37 | return result 38 | ``` -------------------------------------------------------------------------------- /Backtracking/read/200._number_of_islands.md: -------------------------------------------------------------------------------- 1 | # 200. Number of Islands 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/number-of-islands/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. 15 | 16 | Example 1: 17 | 18 | Input: 19 | 11110 20 | 11010 21 | 11000 22 | 00000 23 | 24 | Output: 1 25 | Example 2: 26 | 27 | Input: 28 | 11000 29 | 11000 30 | 00100 31 | 00011 32 | 33 | Output: 3 34 | ``` 35 | 36 | ## 解题方案 37 | 38 | > 思路 1 39 | 40 | 厉害的解法:Sink and count the islands. 41 | 42 | 就是说从(0,0)这个点开始,只要一碰到1就将我们最终island数加1,并且同时将其周围临近的所有1全部都变成0,这样后面就不会重复计算了 43 | 44 | ```python 45 | class Solution(object): 46 | def numIslands(self, grid): 47 | """ 48 | :type grid: List[List[str]] 49 | :rtype: int 50 | """ 51 | def sink(i, j): 52 | if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == '1': 53 | grid[i][j] = '0' 54 | map(sink, (i+1, i-1, i, i), (j, j, j+1, j-1)) 55 | return 1 56 | return 0 57 | return sum(sink(i, j) for i in range(len(grid)) for j in range(len(grid[0]))) 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /Backtracking/read/216._combination_sum_iii.md: -------------------------------------------------------------------------------- 1 | ###216. Combination Sum III 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 继续Combination Sum 系列 13 | 14 | 15 | ``` 16 | class Solution(object): 17 | def combinationSum3(self, k, n): 18 | """ 19 | :type k: int 20 | :type n: int 21 | :rtype: List[List[int]] 22 | """ 23 | candidates = [1,2,3,4,5,6,7,8,9] 24 | self.res = [] 25 | self.combSum(candidates, n, [], k) 26 | return self.res 27 | 28 | 29 | def combSum(self,candidates, target, valueList, k): 30 | if target == 0 and k == 0: 31 | self.res.append(valueList) 32 | length = len(candidates) 33 | if length == 0 or k < 0 : 34 | return 35 | for i in range(length): 36 | if candidates[i] > target: 37 | return 38 | self.combSum(candidates[i+1:], target - candidates[i], valueList + [candidates[i]], k-1) 39 | 40 | ``` -------------------------------------------------------------------------------- /Binary-search/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Binary-search/.DS_Store -------------------------------------------------------------------------------- /Binary-search/240._search_a_2d_matrix_ii.md: -------------------------------------------------------------------------------- 1 | ### 240. Search a 2D Matrix II 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Medium 11 | 12 | 思路: 13 | 14 | 每行,每列都是sorted 15 | 16 | 但是比较好的策略是从右上角开始搜索,比如这样: 17 | 18 | ``` 19 | matrix = [ 20 | [1, 4, 7, 11, 15], 21 | [2, 5, 8, 12, 19], 22 | [3, 6, 9, 16, 22], 23 | [10, 13, 14, 17, 24], 24 | [18, 21, 23, 26, 30] 25 | ] 26 | 27 | m, n = 0, col - 1 28 | 更新策略: 29 | matrix[m][n] < target: 那么这一行到从左走到此都会小于target,row+1 ,往下走 30 | matrix[m][n] > target: 那么这一列往下走都会大于target,col - 1,往左走 31 | 否则找到 32 | ``` 33 | 34 | 时间复杂度O(max(M,N)),因为每次都会往下或者往左走 35 | 36 | 37 | 用的算法是Saddleback 38 | 39 | 40 | 41 | ```python 42 | class Solution(object): 43 | def searchMatrix(self, matrix, target): 44 | """ 45 | :type matrix: List[List[int]] 46 | :type target: int 47 | :rtype: bool 48 | """ 49 | if not matrix: 50 | return False 51 | row = len(matrix) 52 | col = len(matrix[0]) if row else 0 53 | m, n = 0, col - 1 54 | while m < row and n >= 0: 55 | if matrix[m][n] < target: 56 | m += 1 57 | elif matrix[m][n] > target: 58 | n -= 1 59 | else: 60 | return True 61 | return False 62 | 63 | ``` 64 | -------------------------------------------------------------------------------- /Binary-search/read/162._find_peak_element.md: -------------------------------------------------------------------------------- 1 | ### 162. Find Peak Element 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 11 | 思路: 12 | 13 | 14 | 最直观的是O(N)解法 15 | 16 | ```python 17 | class Solution(object): 18 | def findPeakElement(self, nums): 19 | """ 20 | :type nums: List[int] 21 | :rtype: int 22 | """ 23 | for i in range(1, len(nums)): 24 | if nums[i] < nums[i-1]: 25 | return i-1 26 | return len(nums) - 1 27 | ``` 28 | 29 | O(lgN) 解法 30 | 31 | 这是一个经典题目 32 | 33 | - a[mid] < a[mid] only look at the left side 34 | - a[mid] < a[mid] only look at the right side 35 | - else peak found 36 | 37 | 38 | 证明就是用反证法,或者看peak,因为这里已经限制了num[i] ≠ num[i+1],所以peak element 一定存在。然后a[mid] < a[mid-1],那么说明这里一定是下降的,说明之前一定有一个peak存在,否则我们可以用反证法证明. 39 | 40 | 写到这里,我非常相信就是binary search能写对其实不容易。 41 | 42 | 43 | AC代码 44 | 45 | ```python 46 | class Solution(object): 47 | def findPeakElement(self, nums): 48 | """ 49 | :type nums: List[int] 50 | :rtype: int 51 | """ 52 | l, r = 0, len(nums) - 1 53 | while l <= r: 54 | if l == r : return l 55 | mid = l + ((r - l) >> 2) 56 | if nums[mid] < nums[mid+1]: 57 | l = mid + 1 58 | else: 59 | r = mid 60 | ``` 61 | 62 | -------------------------------------------------------------------------------- /Bit-manipulation/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Bit-manipulation/.DS_Store -------------------------------------------------------------------------------- /Bit-manipulation/read/136._single_number.md: -------------------------------------------------------------------------------- 1 | # 136. Single Number 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/single-number/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a non-empty array of integers, every element appears twice except for one. Find that single one. 15 | 16 | Note: 17 | 18 | Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 19 | 20 | Example 1: 21 | 22 | Input: [2,2,1] 23 | Output: 1 24 | Example 2: 25 | 26 | Input: [4,1,2,1,2] 27 | Output: 4 28 | ``` 29 | 30 | ## 解题方案 31 | 32 | > 思路 1 33 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 34 | 35 | 位运算,终于要take it了 36 | 37 | 非常常见的一道算法题,将所有数字进行异或操作即可。对于异或操作明确以下三点: 38 | 39 | - 一个整数与自己异或的结果是0 40 | - 一个整数与0异或的结果是自己 41 | - 异或操作满足交换律,即a^b=b^a 42 | 43 | Python的位操作: 44 | 45 | 46 | 47 | 48 | 49 | ```python 50 | class Solution(object): 51 | def singleNumber(self, nums): 52 | """ 53 | :type nums: List[int] 54 | :rtype: int 55 | """ 56 | res = nums[0] 57 | for i in nums[1:]: 58 | res ^= i 59 | return res 60 | ``` 61 | 62 | -------------------------------------------------------------------------------- /Bit-manipulation/read/191._number_of_1_bits.md: -------------------------------------------------------------------------------- 1 | ### 191. Number of 1 Bits 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 转成二进制,数1的个数 14 | 15 | ```python 16 | class Solution(object): 17 | def hammingWeight(self, n): 18 | """ 19 | :type n: int 20 | :rtype: int 21 | """ 22 | return bin(n).count('1') 23 | ``` 24 | 25 | 26 | 27 | 有wikipedia的题目 [Hamming Weight]((https://zh.wikipedia.org/wiki/汉明重量)) 28 | 29 | 30 | 31 | 用wikipedia的解法: 32 | 33 | 原理是在于每次使用x & x-1 总会把低位的数字给置0 34 | 35 | 比如 3 = 011 2 = 010 3 & 2 = 010 cnt =1 36 | 37 | ​ 2 = 010 1 = 001 2 & 1 = 000 cnt = 2 38 | 39 | 比如 9 = 1001 8 = 1000 9&8 = 1000 cnt =1 40 | 41 | ​ 8 = 1000 7 = 0111 8&7 = 0000 cnt = 2 42 | 43 | > 减1操作将最右边的符号从0变到1,从1变到0,与操作将会移除最右端的1。如果最初X有N个1,那么经过N次这样的迭代运算,X将减到0。下面的算法就是根据这个原理实现的。 44 | 45 | 所以关键点是每次都会把最右边的1变成0. 46 | 47 | 48 | 49 | AC代码 50 | 51 | 52 | 53 | ```python 54 | class Solution(object): 55 | def hammingWeight(self, n): 56 | """ 57 | :type n: int 58 | :rtype: int 59 | """ 60 | cnt = 0 61 | while n != 0: 62 | n &= n - 1 63 | cnt += 1 64 | return cnt 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /Bit-manipulation/read/217._contains_duplicate.md: -------------------------------------------------------------------------------- 1 | # 217. Contains Duplicate 2 | **难度: 简单** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/contains-duplicate/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | 14 | Given an array of integers, find if the array contains any duplicates. 15 | 16 | Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. 17 | 18 | Example 1: 19 | 20 | Input: [1,2,3,1] 21 | Output: true 22 | Example 2: 23 | 24 | Input: [1,2,3,4] 25 | Output: false 26 | Example 3: 27 | 28 | Input: [1,1,1,3,3,4,3,2,4,2] 29 | Output: true 30 | ``` 31 | 32 | ## 解题方案 33 | 34 | > 思路 1 35 | 36 | 利用set怎么可以这么简单。。。。 37 | 38 | 39 | ```python 40 | class Solution(object): 41 | def containsDuplicate(self, nums): 42 | """ 43 | :type nums: List[int] 44 | :rtype: bool 45 | """ 46 | return len(nums) != len(set(nums)) 47 | ``` 48 | 49 | 50 | > 思路 2 51 | 52 | 或者先 sort 也可以 53 | 54 | ```python 55 | class Solution(object): 56 | def containsDuplicate(self, nums): 57 | """ 58 | :type nums: List[int] 59 | :rtype: bool 60 | """ 61 | nums.sort() 62 | for i in range(len(nums)-1): 63 | if nums[i] == nums[i+1]: 64 | return True 65 | return False 66 | ``` 67 | -------------------------------------------------------------------------------- /DP/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/DP/.DS_Store -------------------------------------------------------------------------------- /DP/014._longest_common_prefix.md: -------------------------------------------------------------------------------- 1 | ### 14. Longest Common Prefix 2 | 3 | #### 解法2: 4 | - dp[i]代表前i+1个字符串的最大前缀串, 5 | - 如果第i+2个字符串不以dp[i]为前缀,就去掉dp[i]的最后一个字符再试一次 6 | - 都去完了那么dp[i+1]肯定就是空串了,也就等于这时候的dp[i],因为dp[i]的每个字符已经被去完了 7 | ```python 8 | class Solution(object): 9 | def longestCommonPrefix(self, strs): 10 | """ 11 | :type strs: List[str] 12 | :rtype: str 13 | """ 14 | if not strs: 15 | return '' 16 | dp = [strs[0]]*len(strs) 17 | for i in range(1,len(strs)): 18 | while not strs[i].startswith(dp[i-1]): 19 | dp[i-1] = dp[i-1][:-1] 20 | dp[i] = dp[i-1] 21 | return dp[-1] 22 | ``` -------------------------------------------------------------------------------- /DP/read/044._wildcard_matching.md: -------------------------------------------------------------------------------- 1 | ###44. Wildcard Matching 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Hard 10 | 11 | 12 | 13 | 做完Regular Expression Matching来做的这道题,按照DP思路run一下是超时,感觉是开心的,至少暂时没有报错了,有待优化,应该在dp的同时在贪心一下么。 14 | 15 | 16 | 17 | 超时代码 18 | ``` 19 | class Solution(object): 20 | def isMatch(self, s, p): 21 | """ 22 | :type s: str 23 | :type p: str 24 | :rtype: bool 25 | """ 26 | m, n = len(s), len(p) 27 | dp = [ [0 for i in xrange(n+1)] for j in xrange(m+1)] 28 | 29 | dp[0][0] = 1 30 | 31 | # init the first line 32 | for i in xrange(1,n+1): 33 | if p[i-1] == '*': 34 | dp[0][i] = dp[0][i-1] 35 | 36 | for i in xrange(1,m+1): 37 | for j in xrange(1,n+1): 38 | if p[j-1] == s[i-1] or p[j-1] == '?': 39 | dp[i][j] = dp[i-1][j-1] 40 | elif p[j-1] == '*': 41 | dp[i][j] = dp[i][j-1] or dp[i-1][j] 42 | 43 | return dp[m][n] == 1 44 | ``` -------------------------------------------------------------------------------- /DP/read/064._minimum_path_sum.md: -------------------------------------------------------------------------------- 1 | # 64. Minimum Path Sum 最小路径和 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/minimum-path-sum 10 | * https://leetcode-cn.com/problems/minimum-path-sum/description 11 | 12 | > 内容描述 13 | 14 | ``` 15 | 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 16 | 17 | 说明:每次只能向下或者向右移动一步。 18 | 19 | 示例: 20 | 21 | 输入: 22 | [ 23 | [1,3,1], 24 | [1,5,1], 25 | [4,2,1] 26 | ] 27 | 输出: 7 28 | 解释: 因为路径 1→3→1→1→1 的总和最小。 29 | ``` 30 | 31 | ## 解题方案 32 | 33 | > 思路 1 34 | 35 | * 经典的动态规划问题,和:72. 编辑距离 类似 36 | 37 | ```python 38 | class Solution(object): 39 | def minPathSum(self, grid): 40 | if len(grid) == 0: 41 | return 0 42 | for i in range(0, len(grid)): 43 | for j in range(0, len(grid[0])): 44 | if i == 0 and j != 0: 45 | grid[i][j] += grid[i][j-1] 46 | elif j == 0 and i != 0: 47 | grid[i][j] += grid[i-1][j] 48 | elif i != 0 and j != 0: 49 | grid[i][j] += min(grid[i][j-1], grid[i-1][j]) 50 | return grid[len(grid) - 1][len(grid[0]) - 1] 51 | ``` 52 | -------------------------------------------------------------------------------- /DP/read/091._decode_ways.md: -------------------------------------------------------------------------------- 1 | ### 91. Decode Ways 2 | 3 | 题目: 4 | 5 | 6 | tag : DP 7 | 8 | 难度 : Medium 9 | 10 | ```md 11 | BASE CASE(len(s) = 1 和 len(s) = 2 ): 12 | 直接check 13 | 14 | 非BASE CASE : 15 | 先令 dp[i] = 0 16 | 如果s[i]是可以map的话 -> dp[i] += dp[i-1] 原本的s[0..i]decode方式加上s[i] 17 | 如果s[i-1,i]可以map的话 -> dp[i] += dp[i-2] 原本的s[0...i-1]decode方式加上s[i-1,i] 18 | ``` 19 | 20 | Python代码(可美化) 21 | 22 | ```Python 23 | class Solution: 24 | # @param s, a string 25 | # @return an integer 26 | def numDecodings(self, s): 27 | #dp[i] = dp[i-1] if s[i] != "0" 28 | # +dp[i-2] if "09" < s[i-1:i+1] < "27" 29 | if s == "": return 0 30 | dp = [0 for x in range(len(s)+1)] 31 | dp[0] = 1 32 | for i in range(1, len(s)+1): 33 | if s[i-1] != "0": 34 | dp[i] += dp[i-1] 35 | if i != 1 and s[i-2:i] < "27" and s[i-2:i] > "09": #"01"ways = 0 36 | dp[i] += dp[i-2] 37 | return dp[len(s)] 38 | ``` 39 | -------------------------------------------------------------------------------- /DP/read/093._restore_ip_addresses.md: -------------------------------------------------------------------------------- 1 | ### 93. Restore IP Addresses 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: Medium 8 | 9 | ```py 10 | class Solution(object): 11 | def restoreIpAddresses(self, s): 12 | """ 13 | :type s: str 14 | :rtype: List[str] 15 | """ 16 | ans = [] 17 | self.dfs(ans, s, 4, []) 18 | return ['.'.join(x) for x in ans] 19 | 20 | def dfs(self, ans, s, k, temp): 21 | # pruning 22 | if len(s) > k * 3: 23 | return 24 | if k == 0: 25 | ans.append(temp[:]) 26 | else: 27 | for i in range(min(3, len(s) - k + 1)): 28 | # 2 corner cases: 29 | # 1. range == 2 and the s[range] > 255 30 | # 2. range > 0 and s[0] == 0 31 | if i == 2 and int(s[:3]) > 255 \ 32 | or i > 0 and s[0] == '0': 33 | continue 34 | self.dfs(ans, s[i+1: ], k-1, temp + [s[: i+1]]) 35 | ``` 36 | -------------------------------------------------------------------------------- /DP/read/119. _Pascal's_Triangle_II.md: -------------------------------------------------------------------------------- 1 | # 119. Pascal's Triangle II 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/pascals-triangle-ii/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a non-negative index k where k ≤ 33, return the kth index row of the Pascal's triangle. 15 | 16 | Note that the row index starts from 0. 17 | ``` 18 | 19 | ![](https://github.com/apachecn/LeetCode/blob/master/images/118/PascalTriangleAnimated2.gif) 20 | 21 | ``` 22 | In Pascal's triangle, each number is the sum of the two numbers directly above it. 23 | 24 | Example: 25 | 26 | Input: 3 27 | Output: [1,3,3,1] 28 | Follow up: 29 | 30 | Could you optimize your algorithm to use only O(k) extra space? 31 | ``` 32 | 33 | ## 解题方案 34 | 35 | > 思路 1 36 | ******- 时间复杂度: O(k^2)******- 空间复杂度: O(k)****** 37 | 38 | 太简单了,注意一点算数就好, beats 99.89% 39 | 40 | 41 | ```python 42 | class Solution(object): 43 | def getRow(self, rowIndex): 44 | """ 45 | :type rowIndex: int 46 | :rtype: List[int] 47 | """ 48 | if rowIndex == 0: 49 | return [1] 50 | res = [1] 51 | for i in range(1, rowIndex+1): 52 | tmp = [1] 53 | for j in range(1, i): 54 | tmp.append(res[j-1]+res[j]) 55 | tmp.append(1) 56 | res = tmp 57 | return res 58 | ``` 59 | -------------------------------------------------------------------------------- /DP/read/120. Triangle.md: -------------------------------------------------------------------------------- 1 | ### 120. Triangle 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 思路: 11 | 12 | 先是要注意下这句话:**Each step you may move to adjacent numbers on the row below** 13 | 14 | 在考虑adjacent number的定义,并不是角标的adjacent,而是真的形态上的adjacent 15 | 16 | 比如 17 | 18 | ``` 19 | -1 -1 20 | 2 1 最小 1 0 21 | -2 2 0 -1 2 0 22 | ``` 23 | 24 | 最小是-1, 而并不能从第二排的0跳到第三排的第一个造成-2. 25 | 26 | so AC代码 27 | 28 | 感觉关于dp,我可能还需要补一些东西,因为我不能做到O(n) space 29 | 30 | ``` 31 | class Solution(object): 32 | def minimumTotal(self, triangle): 33 | """ 34 | :type triangle: List[List[int]] 35 | :rtype: int 36 | """ 37 | # n total rows of triangle 38 | n = len(triangle) 39 | if n == 1: return triangle[0][0] 40 | elif n == 2 : return min(triangle[0][0] + triangle[1][0], triangle[0][0] + triangle[1][1]) 41 | else: 42 | res = [] 43 | for i in range(n): 44 | res.append(triangle[i]) 45 | 46 | res[0] = [triangle[0][0]] 47 | res[1] = [triangle[0][0] + triangle[1][0], triangle[0][0] + triangle[1][1]] 48 | 49 | for i in range(2,n): 50 | for j in range(i+1): 51 | if j == 0: 52 | res[i][j] = res[i-1][j] + triangle[i][j] 53 | elif j == i: 54 | res[i][j] = res[i-1][-1] + triangle[i][j] 55 | else: 56 | res[i][j] = min(res[i-1][j-1],res[i-1][j]) + triangle[i][j] 57 | 58 | return min(res[-1]) 59 | ``` 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /DP/read/131._palindrome_partitioning.md: -------------------------------------------------------------------------------- 1 | ###131. Palindrome Partitioning 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 知道一定是用递归做,但是在怎么拆的部分疑惑了,然后看了hint 11 | 12 | key部分长这样,拆法是类似于combination,然后这个len(s) == 0是确保能被拆为palindrome,因为这样剩下的string才是空的 13 | 14 | 15 | 这个recursion tree是这样的,感觉时间复杂度是O(n!),因为每次树都branch n个分支 16 | 17 | ``` 18 | 19 | class Solution(object): 20 | def partition(self, s): 21 | """ 22 | :type s: str 23 | :rtype: List[List[str]] 24 | """ 25 | self.res = [] 26 | self.dfs(s,[]) 27 | return self.res 28 | 29 | 30 | def dfs(self, s, stringList): 31 | if len(s) == 0: 32 | self.res.append(stringList) 33 | for i in range(1,len(s)+1): 34 | if self.isPalindrome(s[:i]): 35 | self.dfs(s[i:],stringList + [s[:i]]) 36 | 37 | def isPalindrome(self, s): 38 | if len(s) <= 1: 39 | return True 40 | return s[0] == s[-1] and self.isPalindrome(s[1:-1]) 41 | 42 | a = Solution() 43 | print a.partition("aab") 44 | 45 | # [['a', 'a', 'b'], ['aa', 'b']] 46 | ``` 47 | 48 | 输出是每次必定从单个char的list开始,然后单个char 配 palindrome word,然后palindrome word再来配char... -------------------------------------------------------------------------------- /DP/read/139._word_break.md: -------------------------------------------------------------------------------- 1 | ### 139. Word Break 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Medium 10 | 11 | 12 | 13 | ```ok[i]``` tells whether ```s[:i]``` can be built. 14 | 15 | ```python 16 | class Solution(object): 17 | def wordBreak(self, s, wordDict): 18 | """ 19 | :type s: str 20 | :type wordDict: List[str] 21 | :rtype: bool 22 | """ 23 | ok = [True] 24 | for i in range(1, len(s)+1): 25 | ok += [any(ok[j] and s[j:i] in wordDict for j in range(i))] 26 | return ok[-1] 27 | ``` 28 | 29 | 但是往list里面加数据的方法有快有慢,下面是对比: 30 | ``` 31 | >>> from timeit import timeit 32 | >>> timeit('x.append(1)', 'x = []', number=10000000) 33 | 1.9880003412529277 34 | >>> timeit('x += 1,', 'x = []', number=10000000) 35 | 1.2676891852971721 36 | >>> timeit('x += [1]', 'x = []', number=10000000) 37 | 3.361207239950204 38 | ``` 39 | 因此我们可以将代码直接换成下面的格式 40 | ```python 41 | ok += any(ok[j] and s[j:i] in wordDict for j in range(i)) # 会报错 42 | ``` 43 | 但是这样会报错,TypeError: 'bool' object is not iterable,因此bool类型数据不能这样加,别的可以(list类型本身当然要注意哈) 44 | 45 | 因此在这个例子中我们这样: 46 | ```python 47 | class Solution(object): 48 | def wordBreak(self, s, wordDict): 49 | """ 50 | :type s: str 51 | :type wordDict: List[str] 52 | :rtype: bool 53 | """ 54 | ok = [True] 55 | for i in range(1, len(s)+1): 56 | ok += any(ok[j] and s[j:i] in wordDict for j in range(i)), 57 | return ok[-1] 58 | ``` 59 | 代码里面的那个逗号构建了一个tuple,也会快一点 60 | -------------------------------------------------------------------------------- /DP/read/152._maximum_product_subarray.md: -------------------------------------------------------------------------------- 1 | ###152. Maximum Product Subarray 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Medium 11 | 12 | 思路: 13 | 14 | 粗一看, 一股浓烈的DP气息飘来,想要套用53题的思路和方程。但是这个跟sum是不一样的,因为乘积可以正负正负的跳,这样的动归方程肯定是不对的 15 | 16 | dp[i] = max(dp[i-1] * a[i],a[i]) 17 | 18 | 举个例子 : [-2,3,-4] 19 | 20 | 21 | 用O(N^2)超时,厉害啊! 22 | 23 | 想,可不可以记录+的和-的,记录两个dp数组,我哭了,真的是这样做的 24 | 25 | 最大值可能来源于最小值 -> 哲学般的句子 26 | 27 | ``` 28 | class Solution(object): 29 | def maxProduct(self, nums): 30 | """ 31 | :type nums: List[int] 32 | :rtype: int 33 | """ 34 | n = len(nums) 35 | maxdp = [ nums[0] for i in range(n)] 36 | mindp = [ nums[0] for i in range(n)] 37 | 38 | 39 | for i in range(1,n): 40 | maxdp[i] = max(mindp[i-1]*nums[i], maxdp[i-1]*nums[i],nums[i]) 41 | mindp[i] = min(maxdp[i-1]*nums[i], mindp[i-1]*nums[i],nums[i]) 42 | 43 | return max(maxdp) 44 | ``` 45 | -------------------------------------------------------------------------------- /DP/read/221._maximal_square.md: -------------------------------------------------------------------------------- 1 | ###221. Maximal Square 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | Medium 10 | 11 | tag: DP 12 | 13 | 14 | 递推公式,一开始想的很简单: 15 | 16 | dp[i][j] = dp[i-1][j-1] + 1 #如果dp[i-1][j-1]为1,dp[i-1][j]为1,dp[i][j-1]为1 17 | 18 | 很明显的错误,一旦遇到更大的方块就会有问题 19 | 20 | 然后看了hint,其实递推方程式是很有技巧的,左上角,左边,上面,相邻的三个部分最小的+1,当然,前提也是要这里dp[i][j] 为1,然后我们再会去看其他的部分。 21 | 22 | 看个例子 23 | 24 | ``` 25 | 原本的matrix DP 26 | 27 | 1 0 1 0 0 1 0 1 0 0 28 | 1 0 1 1 1 → 1 0 1 1 1 29 | 1 1 1 1 1 1 1 1 2 2 30 | 1 0 0 1 0 1 0 0 1 0 31 | 32 | ``` 33 | 34 | 是非常make sense的,因为最小的必定包括了周边的1,然后再加1,否则如果是0的话那么就为0. 35 | 36 | 而naïve的错误的递推公式是因为一个square考虑的部分是k * k的部分, k * k 部分都必定为1. 37 | 38 | 而正确的递推公式 39 | 40 | 41 | dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1]) + 1 42 | 43 | 则完美的考虑了这一情况 44 | 45 | 46 | ``` 47 | class Solution(object): 48 | def maximalSquare(self, matrix): 49 | """ 50 | :type matrix: List[List[str]] 51 | :rtype: int 52 | """ 53 | dp = [] 54 | for i in matrix: 55 | tmp = [] 56 | for j in i: 57 | tmp.append(int(j)) 58 | dp.append(tmp) 59 | 60 | row = len(dp) 61 | col = len(dp[0]) if row else 0 62 | 63 | 64 | for i in range(1,row): 65 | for j in range(1,col): 66 | if dp[i][j] == 1: 67 | dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1]) + 1 68 | 69 | 70 | maxv = 0 71 | for i in range(row): 72 | for j in range(col): 73 | if dp[i][j] > maxv: 74 | maxv = dp[i][j] 75 | return maxv * maxv 76 | ``` 77 | 78 | 79 | -------------------------------------------------------------------------------- /Linked-list/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Linked-list/.DS_Store -------------------------------------------------------------------------------- /Linked-list/369.Plus One Linked List.md: -------------------------------------------------------------------------------- 1 | ### 369.Plus One Linked List 2 | 3 | 题目: 4 | 5 | 6 | 难度 : Medium 7 | 8 | 9 | 10 | 类似题目: plus one,plus one 用递归和循环写了,对于linked list,因为most significant digit在首位,递归写起来不方便,用循环尝试,然后代码并没有实质上的区别。 11 | 12 | 13 | 14 | ``` 15 | class Solution(object): 16 | def plusOne(self, head): 17 | """ 18 | :type head: ListNode 19 | :rtype: ListNode 20 | """ 21 | lst = [] 22 | cur = head 23 | 24 | while cur: 25 | lst.append(cur) 26 | cur = cur.next 27 | 28 | carry = 1 29 | for i in range(len(lst)-1,-1,-1): 30 | lst[i].val += carry 31 | if lst[i].val < 10: 32 | carry = 0 33 | break 34 | else: 35 | lst[i].val -= 10 36 | 37 | if carry == 1: 38 | node = ListNode(1) 39 | node.next = head 40 | return node 41 | else: 42 | return head 43 | ``` 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Linked-list/read/019._remove_nth_node_from_end_of_list.md: -------------------------------------------------------------------------------- 1 | ### 19. Remove Nth Node From End of List 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: Medium 9 | 10 | 11 | AC击败了95.80%的Python用户,技巧 dummy head 和双指针。 12 | 13 | 切记最后要返回```dummy.next```而不是```head```,因为有这样一种情况,删掉节点后```linked list```空了,那返回```head```的话结果显然不同。如: 14 | 输入链表为```[1]```, ```n = 1```, 应该返回```None```而不是```[1]``` 15 | 16 | ```python 17 | class Solution(object): 18 | def removeNthFromEnd(self, head, n): 19 | """ 20 | :type head: ListNode 21 | :type n: int 22 | :rtype: ListNode 23 | """ 24 | dummy = ListNode(-1) 25 | dummy.next = head 26 | p, q = dummy, dummy 27 | 28 | for i in range(n): 29 | q = q.next 30 | 31 | while q.next: 32 | p = p.next 33 | q = q.next 34 | 35 | p.next = p.next.next 36 | return dummy.next 37 | 38 | ``` 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Linked-list/read/021._merge_two_sorted_lists.md: -------------------------------------------------------------------------------- 1 | # 21. Merge Two Sorted Lists 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/merge-two-sorted-lists/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 15 | 16 | Example: 17 | 18 | Input: 1->2->4, 1->3->4 19 | Output: 1->1->2->3->4->4 20 | ``` 21 | 22 | ## 解题方案 23 | 24 | > 思路 1 25 | 26 | 同样适用dummy head 27 | 28 | ```python 29 | class Solution(object): 30 | def mergeTwoLists(self, l1, l2): 31 | """ 32 | :type l1: ListNode 33 | :type l2: ListNode 34 | :rtype: ListNode 35 | """ 36 | if l1 == None: 37 | return l2 38 | if l2 == None: 39 | return l1 40 | 41 | dummy = ListNode(-1) 42 | cur = dummy 43 | 44 | while l1 and l2: 45 | if l1.val < l2.val: 46 | cur.next = l1 47 | l1 = l1.next 48 | else: 49 | cur.next = l2 50 | l2 = l2.next 51 | cur = cur.next 52 | 53 | if l1: 54 | cur.next = l1 55 | else: 56 | cur.next = l2 57 | return dummy.next 58 | 59 | ``` 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Linked-list/read/024._swap_nodes_in_pairs.md: -------------------------------------------------------------------------------- 1 | ### 24. Swap Nodes in Pairs 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Medium 8 | 9 | 一眼就知道这个用递归做,```beats 96.06%``` 10 | ```python 11 | class Solution(object): 12 | def swapPairs(self, head): 13 | """ 14 | :type head: ListNode 15 | :rtype: ListNode 16 | """ 17 | if not head: 18 | return None 19 | if not head.next: 20 | return head 21 | tmp = head.next 22 | head.next = self.swapPairs(head.next.next) 23 | tmp.next = head 24 | return tmp 25 | ``` 26 | 27 | 或者用```loop```做,每个```node```关系要弄清楚, 又是巧用```dummy```,```dummy```大法对于```nodeList```的题目简直无敌!!!🐂批, 但是只```beats```了```69.40%``` 28 | 29 | 30 | ```python 31 | class Solution(object): 32 | def swapPairs(self, head): 33 | """ 34 | :type head: ListNode 35 | :rtype: ListNode 36 | """ 37 | if head == None or head.next == None: 38 | return head 39 | 40 | dummy = ListNode(-1) 41 | dummy.next = head 42 | 43 | cur = dummy 44 | 45 | while cur.next and cur.next.next: 46 | next_one, next_two, next_three = cur.next, cur.next.next, cur.next.next.next 47 | cur.next = next_two 48 | next_two.next = next_one 49 | next_one.next = next_three 50 | cur = next_one 51 | return dummy.next 52 | ``` 53 | -------------------------------------------------------------------------------- /Linked-list/read/061._rotate_list.md: -------------------------------------------------------------------------------- 1 | 2 | ###61. Rotate List 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | 11 | Medium 12 | 13 | - k可能比list的size大,需要做一个取余准备 14 | - 计算list size的同时把tail也记录下来,方便之后把tail的next指向原本的head 15 | - 利用之前的到末端的kth node 16 | 17 | 18 | AC 代码 19 | 20 | ``` 21 | class Solution(object): 22 | def rotateRight(self, head, k): 23 | if head == None or k == 0 : 24 | return head 25 | 26 | cur = head 27 | size = 1 28 | while cur.next: 29 | size += 1 30 | cur = cur.next 31 | 32 | tail = cur 33 | 34 | k = k % size 35 | 36 | p = self.findKth(head,k) 37 | 38 | tail.next = head 39 | head = p.next 40 | p.next = None 41 | return head 42 | 43 | def findKth(self,head, k): 44 | dummy = ListNode(-1) 45 | dummy.next = head 46 | p = dummy 47 | q = dummy 48 | 49 | for i in range(k): 50 | q = q.next 51 | 52 | while q.next: 53 | p = p.next 54 | q = q.next 55 | return p 56 | ``` 57 | 58 | 59 | -------------------------------------------------------------------------------- /Linked-list/read/082._remove_duplicates_from_sorted_list_ii.md: -------------------------------------------------------------------------------- 1 | ###82. Remove Duplicates from Sorted List II 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 9 | 难度: 10 | 11 | Medium 12 | 13 | 14 | 木有space 和 time的限制,第一想法,用dictionary存一下每个nodes的个数,这样只要看到它是大于1的,就删删删。 15 | 16 | 虽然是笨办法。但是也可以AC 17 | 18 | ``` 19 | class Solution(object): 20 | def deleteDuplicates(self, head): 21 | """ 22 | :type head: ListNode 23 | :rtype: ListNode 24 | """ 25 | dummy = ListNode(-1) 26 | dummy.next = head 27 | 28 | cur = dummy.next 29 | nodeNumber = {} 30 | while cur: 31 | if cur.val in nodeNumber: 32 | nodeNumber[cur.val] += 1 33 | else: 34 | nodeNumber[cur.val] = 1 35 | cur = cur.next 36 | 37 | cur = dummy 38 | while cur.next: 39 | if nodeNumber[cur.next.val] > 1: 40 | cur.next = cur.next.next 41 | else: 42 | cur = cur.next 43 | return dummy.next 44 | ``` 45 | 46 | 47 | 谷歌一下,更省时间的方法是用一个prev 和 cur 指针,然后用一个bool来记录是否duplicate,这样loop一次即可解决问题。 48 | 49 | to be 写出来 -------------------------------------------------------------------------------- /Linked-list/read/083._remove_duplicates_from_sorted_list.md: -------------------------------------------------------------------------------- 1 | ### 83. Remove Duplicates from Sorted List 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | dummy 大法 13 | 14 | ```python 15 | class Solution(object): 16 | def deleteDuplicates(self, head): 17 | """ 18 | :type head: ListNode 19 | :rtype: ListNode 20 | """ 21 | dummy = head 22 | while head: 23 | while head.next and head.next.val == head.val: 24 | head.next = head.next.next # skip duplicated node 25 | head = head.next # not duplicate of current node, move to next node 26 | return dummy 27 | ``` 28 | -------------------------------------------------------------------------------- /Linked-list/read/086._partition_list.md: -------------------------------------------------------------------------------- 1 | # 86. Partition List 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/partition-list/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. 15 | 16 | You should preserve the original relative order of the nodes in each of the two partitions. 17 | 18 | Example: 19 | 20 | Input: head = 1->4->3->2->5->2, x = 3 21 | Output: 1->2->2->4->3->5 22 | ``` 23 | 24 | ## 解题方案 25 | 26 | > 思路 1 27 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 28 | 29 | 两个dummy,一个代表before,一个代表behind,最后连接起来就是结果,要注意behind的最后可能还连接着原来的点 30 | 31 | 例如例子中的5,它在最开始后面还连接着1个2,所以要记得将dummy1_end.next置为None 32 | 33 | beats 99.39% 34 | 35 | ```python 36 | class Solution(object): 37 | def partition(self, head, x): 38 | """ 39 | :type head: ListNode 40 | :type x: int 41 | :rtype: ListNode 42 | """ 43 | dummy1_start = dummy1_end = ListNode(None) # before 44 | dummy2_start = dummy2_end = ListNode(None) # behind 45 | while head: 46 | if head.val < x: 47 | dummy1_end.next = head 48 | dummy1_end = dummy1_end.next 49 | else: 50 | dummy2_end.next = head 51 | dummy2_end = dummy2_end.next 52 | head = head.next 53 | # 从例子来看,因为dummy2_end最后指向5,它最开始还连着2呢,所以要置为空 54 | dummy2_end.next = None 55 | dummy1_end.next = dummy2_start.next 56 | return dummy1_start.next 57 | ``` 58 | -------------------------------------------------------------------------------- /Linked-list/read/141._linked_list_cycle.md: -------------------------------------------------------------------------------- 1 | # 141. Linked List Cycle 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/linked-list-cycle/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a linked list, determine if it has a cycle in it. 15 | 16 | Follow up: 17 | Can you solve it without using extra space? 18 | ``` 19 | 20 | ## 解题方案 21 | 22 | > 思路 1 23 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 24 | 25 | 26 | 27 | 用个字典记录某个点是否被访问过,时间,空间复杂度都是O(n) 28 | 29 | beats 96.59% 30 | 31 | ```python 32 | class Solution(object): 33 | def hasCycle(self, head): 34 | """ 35 | :type head: ListNode 36 | :rtype: bool 37 | """ 38 | if not head: 39 | return False 40 | lookup = {} 41 | while head: 42 | if head in lookup: 43 | return True 44 | lookup[head] = 1 45 | head = head.next 46 | return False 47 | ``` 48 | 49 | 50 | 51 | > 思路 2 52 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 53 | 54 | 55 | 快慢指针, beats 96.59% 56 | 57 | ```python 58 | class Solution(object): 59 | def hasCycle(self, head): 60 | """ 61 | :type head: ListNode 62 | :rtype: bool 63 | """ 64 | slow = head 65 | fast = head 66 | while fast and fast.next: 67 | slow = slow.next 68 | fast = fast.next.next 69 | if slow == fast: 70 | return True 71 | return False 72 | ``` 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /Linked-list/read/142_Linked_List_Cycle_II.md: -------------------------------------------------------------------------------- 1 | # 142. Linked List Cycle II 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/linked-list-cycle-ii/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a linked list, return the node where the cycle begins. If there is no cycle, return null. 15 | 16 | Note: Do not modify the linked list. 17 | 18 | Follow up: 19 | Can you solve it without using extra space? 20 | ``` 21 | 22 | ## 解题方案 23 | 24 | > 思路 1 25 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 26 | 27 | 直接快慢指针,跟141一样,。这里注意一下***while-else clause***的用法就行 28 | 29 | beats 99.81% 30 | 31 | ```python 32 | class Solution(object): 33 | def detectCycle(self, head): 34 | """ 35 | :type head: ListNode 36 | :rtype: bool 37 | """ 38 | slow = fast = head 39 | while fast and fast.next: 40 | slow = slow.next 41 | fast = fast.next.next 42 | if slow == fast: 43 | break 44 | else: 45 | return None 46 | while head != slow: 47 | slow = slow.next 48 | head = head.next 49 | return head 50 | ``` 51 | 52 | 53 | -------------------------------------------------------------------------------- /Linked-list/read/147._insertion_sort_list.md: -------------------------------------------------------------------------------- 1 | ###147. Insertion Sort List 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | insertion sort 也是入门必备,一个元素本身被认为是sort的,一个简单的理解是打牌,然后进入第二个元素的时候,看它是比第一个元素大还是小,做排序,进入下一个元素的时候再看再移。 11 | 12 | 伪码 13 | 14 | ``` 15 | for i ← 1 to length(A)-1 16 | j ← i 17 | while j > 0 and A[j-1] > A[j] 18 | swap A[j] and A[j-1] 19 | j ← j - 1 20 | end while 21 | end for 22 | ``` 23 | 24 | 这个伪码对于list可能适用性没有那么强,则考虑,从第二个node开始,那么从开始开始看,找到这个node应该插入的位置,插入。 25 | 26 | 27 | 28 | 就是这样,就是会超时|||| 29 | 30 | ``` 31 | class Solution(object): 32 | def insertionSortList(self, head): 33 | """ 34 | :type head: ListNode 35 | :rtype: ListNode 36 | """ 37 | if head == None or head.next == None: 38 | return head 39 | 40 | dummy = ListNode(-1) 41 | dummy.next = head 42 | 43 | prev = head 44 | cur = head.next 45 | 46 | while cur: 47 | p = dummy 48 | while p.next.val <= cur.val and p != prev: 49 | p = p.next 50 | if p != prev: 51 | prev.next = cur.next 52 | cur.next = p.next 53 | p.next = cur 54 | prev = cur 55 | cur = cur.next 56 | 57 | return dummy.next 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /Linked-list/read/203._remove_linked_list_elements.md: -------------------------------------------------------------------------------- 1 | ###203. Remove Linked List Elements 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | AC代码如下: 13 | 14 | 15 | 16 | ``` 17 | class Solution(object): 18 | def removeElements(self, head, val): 19 | """ 20 | :type head: ListNode 21 | :type val: int 22 | :rtype: ListNode 23 | """ 24 | dummy = ListNode(-1) 25 | dummy.next = head 26 | 27 | cur = dummy 28 | 29 | while cur.next: 30 | if cur.next.val == val: 31 | cur.next = cur.next.next 32 | else: 33 | cur = cur.next 34 | 35 | return dummy.next 36 | 37 | 38 | ``` -------------------------------------------------------------------------------- /Linked-list/read/237._delete_node_in_a_linked_list.md: -------------------------------------------------------------------------------- 1 | ### 237. Delete Node in a Linked List 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Easy 9 | 10 | 11 | 12 | 这道题,第一感觉,像删链表一样来删,把所有的node val前移一个,但是有个问题,为什么tail那个node还是存在?哼(ˉ(∞)ˉ)唧.. 13 | 14 | 已经被解答: 15 | 16 | 17 | 18 | 19 | 20 | 另外一个O(1)的办法更好,把后一个node的val移到待删这个节点,并且把node.next = node.next.next 21 | 22 | 题目说了不会删最后一个点,所以node.next.next一定存在,所以直接让node的val等于它next的val,然后让node的next指向它的next的next,举个例子: 23 | 1->2->3->4->5->None,要删除第四个节点,就让4变成5,然后让第四个节点指向第五个节点的next, 24 | 这样原来的第四个节点就不存在了,虽然原来的第五个节点仍然存在且指向None,变成了1->2->3->5->None-<5 25 | 26 | 27 | 28 | ```python 29 | O(1)时间 30 | class Solution(object): 31 | def deleteNode(self, node): 32 | """ 33 | :type node: ListNode 34 | :rtype: void Do not return anything, modify node in-place instead. 35 | """ 36 | node.val = node.next.val 37 | node.next = node.next.next 38 | ``` 39 | ```python 40 | O(n)时间 41 | class Solution(object): 42 | def deleteNode(self, node): 43 | """ 44 | :type node: ListNode 45 | :rtype: void Do not return anything, modify node in-place instead. 46 | """ 47 | while node.next: 48 | node.val = node.next.val 49 | prev, node = node, node.next 50 | # clear reference to tail 51 | prev.next = None 52 | ``` 53 | -------------------------------------------------------------------------------- /Matrix/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Matrix/.DS_Store -------------------------------------------------------------------------------- /Matrix/read/073. Set Matrix Zeroes.md: -------------------------------------------------------------------------------- 1 | ### 73. Set Matrix Zeroes 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 10 | 难度 : Medium 11 | 12 | 13 | 14 | 思路: 15 | 16 | Naive AC代码,一看类似那个 game of life,不用extra space,不用O(mn),应该就是用状态转移机了(?),所以还是先naive AC把: 17 | 18 | ```python 19 | class Solution(object): 20 | def setZeroes(self, matrix): 21 | """ 22 | :type matrix: List[List[int]] 23 | :rtype: void Do not return anything, modify matrix in-place instead. 24 | """ 25 | def setZero(i,j): 26 | for m in range(col): 27 | matrix[i][m] = 0 28 | for n in range(row): 29 | matrix[n][j] = 0 30 | 31 | row = len(matrix) 32 | col = len(matrix[0]) if row else 0 33 | new_matrix = [matrix[i][:] for i in range(row)] 34 | 35 | for i in range(row): 36 | for j in range(col): 37 | if new_matrix[i][j] == 0: 38 | setZero(i,j) 39 | ``` 40 | 41 | 42 | 43 | `正确思路`: 44 | 45 | 一边遍历,一边将相应的行和列置为0是行不通的,会影响后面元素的遍历判断,所以要记录下哪些行和哪些列是要置为0的。为了节约空间,在原矩阵中借两条边,如果该行或者列要置为0,则把左边或者上边的相应位置置为0。如果左边和上边本来就有0,那么需要额外标记一下,最后把左边或者右边也全部置为0. 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Misc/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Misc/.DS_Store -------------------------------------------------------------------------------- /Misc/read/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Misc/read/.DS_Store -------------------------------------------------------------------------------- /Misc/read/008._string_to_integer_(atoi).md: -------------------------------------------------------------------------------- 1 | ### 8. String to Integer (atoi) 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 11 | 需要考虑比较多的边界条件&特殊情况 12 | 1. 首先输入可能会有空格,所以先去掉空格 13 | 2. 去掉空格后要考虑空字符串情况 14 | 3. 字符串首位可能会有正负号,要考虑 15 | 4. 开始转换成数字,题目说只要遇到非数字就可以break了 16 | 5. 结果太大或者太小超过```int```限制就要返回特定数字 ```2147483647``` 或者 ```-2147483648``` 17 | 6. 根据之前的正负号结果返回对应数值 18 | 19 | 20 | ```python 21 | class Solution(object): 22 | def myAtoi(self, str): 23 | """ 24 | :type str: str 25 | :rtype: int 26 | """ 27 | str = str.strip() 28 | strNum = 0 29 | if len(str) == 0: 30 | return strNum 31 | 32 | positive = True 33 | if str[0] == '+' or str[0] == '-': 34 | if str[0] == '-': 35 | positive = False 36 | str = str[1:] 37 | 38 | for char in str: 39 | if char >='0' and char <='9': 40 | strNum = strNum * 10 + ord(char) - ord('0') 41 | if char < '0' or char > '9': 42 | break 43 | 44 | if strNum > 2147483647: 45 | if positive == False: 46 | return -2147483648 47 | else: 48 | return 2147483647 49 | if not positive: 50 | strNum = 0 - strNum 51 | return strNum 52 | 53 | ``` 54 | -------------------------------------------------------------------------------- /Misc/read/009._Palindrome_Number.md: -------------------------------------------------------------------------------- 1 | # 9. Palindrome Number 回文数 2 | 3 | ## 题目 4 | 5 | * https://leetcode.com/problems/palindrome-number 6 | * https://leetcode-cn.com/problems/palindrome-number/description 7 | 8 | ``` 9 | 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 10 | 11 | 示例 1: 12 | 13 | 输入: 121 14 | 输出: true 15 | 示例 2: 16 | 17 | 输入: -121 18 | 输出: false 19 | 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 20 | 示例 3: 21 | 22 | 输入: 10 23 | 输出: false 24 | 解释: 从右向左读, 为 01 。因此它不是一个回文数。 25 | 进阶: 26 | 27 | 你能不将整数转为字符串来解决这个问题吗? 28 | ``` 29 | 30 | ## 难度:Medium 31 | 32 | > 思路1 (满足Follow up) 33 | 34 | - 首先负数肯定不是palindrome 35 | - 其次如果一个数字是一个正数,并且能被我0整除那它肯定也不是palindrome 36 | 37 | 这样降低了复杂度 38 | 39 | ```python 40 | class Solution(object): 41 | def isPalindrome(self, x): 42 | """ 43 | :type x: int 44 | :rtype: bool 45 | """ 46 | if x < 0 or (x != 0 and x % 10 == 0): 47 | return False 48 | rev, y = 0, x 49 | while x > 0: 50 | rev = rev * 10 + x % 10 51 | x /= 10 52 | return y == rev 53 | 54 | ``` 55 | 56 | > 思路2 57 | 58 | * 排除小于0的数 59 | * 通过字符串进行反转,对比数字是否相等就行 60 | 61 | ```python 62 | class Solution: 63 | def isPalindrome(self, x): 64 | """ 65 | :type x: int 66 | :rtype: bool 67 | """ 68 | if x < 0: 69 | return False 70 | elif x != int(str(x)[::-1]): 71 | return False 72 | else: 73 | return True 74 | ``` 75 | -------------------------------------------------------------------------------- /Misc/read/012._Integer_to_Roman.md: -------------------------------------------------------------------------------- 1 | ### 12. Integer to Roman 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | Medium 10 | 11 | 思路: 12 | 13 | 首先我学习了一下罗马字母是如何表示的。然后感慨,这个阿拉伯数字是多么好的发明 14 | 15 | 16 | 17 | 上图 18 | 19 | 20 | 21 | 基于的是这些个Symbol: 22 | 23 | ``` 24 | 1 5 10 50 100 500 1000 25 | I V X L C D M 26 | ``` 27 | 28 | 29 | 30 | 罗马数字表示法见[Leetcode 013](https://github.com/Lisanaaa/thinking_in_lc/blob/master/013._Roman_to_Integer.md) 31 | 32 | 这里有一个很棒的[算法](https://gist.github.com/imilu/00f32c61e50b7ca296f91e9d96d8e976) 33 | 34 | AC代码 35 | 36 | ```python 37 | class Solution(object): 38 | def intToRoman(self, num): 39 | """ 40 | :type num: int 41 | :rtype: str 42 | """ 43 | lookup = { 44 | 'M': 1000, 45 | 'CM': 900, 46 | 'D': 500, 47 | 'CD': 400, 48 | 'C': 100, 49 | 'XC': 90, 50 | 'L': 50, 51 | 'XL': 40, 52 | 'X': 10, 53 | 'IX': 9, 54 | 'V': 5, 55 | 'IV': 4, 56 | 'I': 1 57 | } 58 | romanStr = '' 59 | 60 | for symbol, val in sorted(lookup.items(), key = lambda t: t[1], reverse = True): 61 | while num >= val: 62 | romanStr += symbol 63 | num -= val 64 | return romanStr 65 | ``` 66 | 67 | 68 | 69 | 70 | 71 | 因为dict本身是无序的,这里做了一个排序的操作,否则可能会出现IIII这种状况。 72 | -------------------------------------------------------------------------------- /Misc/read/027._Remove_Element.md: -------------------------------------------------------------------------------- 1 | ### 27. Remove Element 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 瞬秒 13 | 14 | ```python 15 | class Solution(object): 16 | def removeElement(self, nums, val): 17 | """ 18 | :type nums: List[int] 19 | :type val: int 20 | :rtype: int 21 | """ 22 | while val in nums: 23 | nums.remove(val) 24 | return len(nums) 25 | ``` 26 | -------------------------------------------------------------------------------- /Misc/read/045._Jump_Game_II.md: -------------------------------------------------------------------------------- 1 | ### 45. Jump Game II 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路 13 | 14 | greedy solution, the current jump is ```[i, cur_end]```, and the ```cur_farthest``` is the farthest point 15 | that all of point in ```[i, cur_end]``` can reach, whenever ```cur_farthest``` is larger than the last point' index, 16 | return current ```jump+1```; whenever ```i``` reaches ```cur_end```, update ```cur_end``` to ```current cur_farthest```. 17 | - Time: O(log(n)) 18 | - Space: O(1) 19 | 20 | ```python 21 | class Solution(object): 22 | def jump(self, nums): 23 | """ 24 | :type nums: List[int] 25 | :rtype: int 26 | """ 27 | # Note You can assume that you can always reach the last index. 28 | cur_end, cur_farthest, step, n = 0, 0, 0, len(nums) 29 | for i in range(n-1): 30 | cur_farthest = max(cur_farthest, i + nums[i]) 31 | if cur_farthest >= n - 1: 32 | step += 1 33 | break 34 | if i == cur_end: 35 | cur_end = cur_farthest 36 | step += 1 37 | return step 38 | 39 | 40 | 41 | ``` 42 | 43 | 44 | -------------------------------------------------------------------------------- /Misc/read/049._group_anagrams.md: -------------------------------------------------------------------------------- 1 | # 49. Group Anagrams 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/group-anagrams/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an array of strings, group anagrams together. 15 | 16 | Example: 17 | 18 | Input: ["eat", "tea", "tan", "ate", "nat", "bat"], 19 | Output: 20 | [ 21 | ["ate","eat","tea"], 22 | ["nat","tan"], 23 | ["bat"] 24 | ] 25 | Note: 26 | 27 | All inputs will be in lowercase. 28 | The order of your output does not matter. 29 | ``` 30 | 31 | ## 解题方案 32 | 33 | > 思路 1 34 | 35 | 每一个字符串都先排个序看看是不是一样,这样更好判断 36 | 37 | ```python 38 | class Solution(object): 39 | def groupAnagrams(self, strs): 40 | """ 41 | :type strs: List[str] 42 | :rtype: List[List[str]] 43 | """ 44 | mapx = {} 45 | for i in strs: 46 | tmp = ''.join(sorted(list(i))) 47 | if tmp in mapx: 48 | mapx[tmp].append(i) 49 | else: 50 | mapx[tmp] = [i] 51 | return mapx.values() 52 | ``` 53 | -------------------------------------------------------------------------------- /Misc/read/050._pow(x,_n).md: -------------------------------------------------------------------------------- 1 | # 50. Pow(x, n) 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/powx-n/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Implement pow(x, n), which calculates x raised to the power n (xn). 15 | 16 | Example 1: 17 | 18 | Input: 2.00000, 10 19 | Output: 1024.00000 20 | Example 2: 21 | 22 | Input: 2.10000, 3 23 | Output: 9.26100 24 | Example 3: 25 | 26 | Input: 2.00000, -2 27 | Output: 0.25000 28 | Explanation: 2-2 = 1/22 = 1/4 = 0.25 29 | Note: 30 | 31 | -100.0 < x < 100.0 32 | n is a 32-bit signed integer, within the range [−231, 231 − 1] 33 | ``` 34 | 35 | ## 解题方案 36 | 37 | > 思路 1 38 | 39 | Recursive, beats 100% 40 | 41 | ```python 42 | class Solution(object): 43 | def myPow(self, x, n): 44 | """ 45 | :type x: float 46 | :type n: int 47 | :rtype: float 48 | """ 49 | if n == 0: 50 | return 1 51 | if n < 0: 52 | return 1 / self.myPow(x, -n) 53 | if n & 1: # n 为 奇数 54 | return x * self.myPow(x*x, n>>1) 55 | else: 56 | return self.myPow(x*x, n>>1) 57 | ``` 58 | 59 | > 思路 2 60 | 61 | iterative 62 | 63 | 64 | ```python 65 | class Solution(object): 66 | def myPow(self, x, n): 67 | """ 68 | :type x: float 69 | :type n: int 70 | :rtype: float 71 | """ 72 | if n < 0: 73 | x = 1 / x 74 | n = -n 75 | res = 1 76 | while n: 77 | if n & 1: 78 | res *= x 79 | x *= x 80 | n >>= 1 81 | return res 82 | ``` 83 | -------------------------------------------------------------------------------- /Misc/read/055._jump_game.md: -------------------------------------------------------------------------------- 1 | ### 55. Jump Game 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Medium 10 | 11 | 12 | 问题出现在一旦有0,而且这个0是不可跨过的那么无解,无法达到 13 | 14 | 15 | 看了hint,根本不用这个数组,直接用一个数来记录可达最远距离,非常巧妙 16 | 17 | 18 | ```python 19 | class Solution(object): 20 | def canJump(self, nums): 21 | """ 22 | :type nums: List[int] 23 | :rtype: bool 24 | """ 25 | if not nums: 26 | return True 27 | if len(nums) == 1: 28 | return True 29 | n = len(nums) 30 | idx, reach = 0, 0 31 | while idx < n-1 and idx <= reach: # idx <= reach是为了处理nums[idx] == 0的情况,若idx>reach说明已经失败了 32 | reach = max(reach, idx+nums[idx]) 33 | idx += 1 34 | return reach >= n-1 35 | ``` 36 | 37 | idx记录当前loop位置,reach记录当前可到位置 38 | 39 | 注意这里的while循环的条件是 `idx < n-1 and idx <= reach`,之所以加上 `idx <= reach` 是因为如果```idx > reach```说明```idx```层不可达,其实也可以直接terminate. 40 | -------------------------------------------------------------------------------- /Misc/read/056._Merge_Intervals.md: -------------------------------------------------------------------------------- 1 | # 56. Merge Intervals 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/merge-intervals/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a collection of intervals, merge all overlapping intervals. 15 | 16 | Example 1: 17 | 18 | Input: [[1,3],[2,6],[8,10],[15,18]] 19 | Output: [[1,6],[8,10],[15,18]] 20 | Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. 21 | Example 2: 22 | 23 | Input: [[1,4],[4,5]] 24 | Output: [[1,5]] 25 | Explanation: Intervals [1,4] and [4,5] are considerred overlapping. 26 | ``` 27 | 28 | ## 解题方案 29 | 30 | > 思路 1 31 | 32 | Just go through the intervals sorted by start coordinate and 33 | either combine the current interval with the previous one if they overlap, or add it to the output by itself if they don’t. 34 | 35 | beats 95.48% 36 | 37 | ```python 38 | class Solution(object): 39 | def merge(self, intervals): 40 | """ 41 | :type intervals: List[Interval] 42 | :rtype: List[Interval] 43 | """ 44 | res = [] 45 | for i in sorted(intervals, key = lambda x: x.start): 46 | if res and i.start <= res[-1].end: 47 | res[-1].end = max(res[-1].end, i.end) 48 | else: 49 | res.append(i) 50 | return res 51 | ``` 52 | 53 | 54 | -------------------------------------------------------------------------------- /Misc/read/058._length_of_last_word.md: -------------------------------------------------------------------------------- 1 | ### 58. Length of Last Word 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 我的解法: 10 | 11 | ```python 12 | class Solution(object): 13 | def lengthOfLastWord(self, s): 14 | """ 15 | :type s: str 16 | :rtype: int 17 | """ 18 | s = s[::-1].strip() 19 | return s.find(' ') if s.find(' ') != -1 else len(s) 20 | ``` 21 | 作弊式做法 22 | 23 | ```python 24 | class Solution(object): 25 | def lengthOfLastWord(self, s): 26 | """ 27 | :type s: str 28 | :rtype: int 29 | """ 30 | lst = s.split() 31 | if len(lst) >= 1: 32 | return len(lst[-1]) 33 | return 0 34 | ``` 35 | split()方法最低可以分0组,split(' ')最低可以分1组 36 | ```python 37 | 一行解法: 38 | class Solution(object): 39 | def lengthOfLastWord(self, s): 40 | """ 41 | :type s: str 42 | :rtype: int 43 | """ 44 | return len(s.strip().split(" ")[-1]) 45 | ``` 46 | -------------------------------------------------------------------------------- /Misc/read/066._plus_one.md: -------------------------------------------------------------------------------- 1 | ### 66. Plus One 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 10 | 11 | 12 | 这里是用的递归,很容易理解,如果空列表直接加1,最后一位小于9,那么直接就最后一位加1,否则添加一个0,然后再把余下的递归加1 13 | 14 | 15 | ```python 16 | 17 | class Solution(object): 18 | def plusOne(self, digits): 19 | """ 20 | :type digits: List[int] 21 | :rtype: List[int] 22 | """ 23 | if digits == []: 24 | return [1] 25 | if digits[-1] < 9: 26 | return digits[:-1] + [digits[-1] + 1] 27 | else: 28 | return self.plusOne(digits[:-1]) + [0] 29 | ``` 30 | 31 | 32 | 其实可以考虑循环,效率更高,参考[此处](https://shenjie1993.gitbooks.io/leetcode-python/content/066%20Plus%20One.html) 33 | 34 | 35 | 36 | > 从低位到高位,如果后一位有进位的话,那么该位要加上一,否则退出循环。如果最高位也进位,那么在列表前要插入一个一。 37 | 38 | 39 | 40 | ``` 41 | class Solution(object): 42 | def plusOne(self, digits): 43 | """ 44 | :type digits: List[int] 45 | :rtype: List[int] 46 | """ 47 | carry = 1 48 | 49 | for i in range(len(digits)-1,-1,-1): 50 | digits[i] += carry 51 | if digits[i] < 10: 52 | carry = 0 53 | break 54 | else: 55 | digits[i] -= 10 56 | if carry == 1: 57 | digits.insert(0,1) 58 | return digits 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /Misc/read/067._add_binary.md: -------------------------------------------------------------------------------- 1 | # 67. Add Binary 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/add-binary/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given two binary strings, return their sum (also a binary string). 15 | 16 | The input strings are both non-empty and contains only characters 1 or 0. 17 | 18 | Example 1: 19 | 20 | Input: a = "11", b = "1" 21 | Output: "100" 22 | Example 2: 23 | 24 | Input: a = "1010", b = "1011" 25 | Output: "10101" 26 | ``` 27 | 28 | ## 解题方案 29 | 30 | > 思路 1 31 | 32 | 几种case: 33 | 34 | - a or b 为空,最简单 35 | - 唯一的问题是如果有进位的处理,进位的处理就是先让其中的一个数和```‘1’```做```addBinary```处理 ,然后再用```addBinary``` 36 | 37 | ```python 38 | class Solution(object): 39 | def addBinary(self, a, b): 40 | """ 41 | :type a: str 42 | :type b: str 43 | :rtype: str 44 | """ 45 | if a == '' or b == '': 46 | return a + b 47 | if a[-1] == '0' and b[-1] == '0': 48 | return self.addBinary(a[:-1], b[:-1]) + '0' 49 | elif a[-1] == '1' and b[-1] == '1': 50 | return self.addBinary(a[:-1], self.addBinary(b[:-1], '1')) + '0' 51 | else: 52 | return self.addBinary(a[:-1], b[:-1]) + '1' 53 | ``` 54 | -------------------------------------------------------------------------------- /Misc/read/088._merge_sorted_array.md: -------------------------------------------------------------------------------- 1 | # 88. Merge Sorted Array 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/merge-sorted-array/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 15 | 16 | Note: 17 | 18 | The number of elements initialized in nums1 and nums2 are m and n respectively. 19 | You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. 20 | Example: 21 | 22 | Input: 23 | nums1 = [1,2,3,0,0,0], m = 3 24 | nums2 = [2,5,6], n = 3 25 | 26 | Output: [1,2,2,3,5,6] 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | 33 | 给的数组可能是这样的 34 | 35 | - nums1 : [0] 36 | - m : 0 37 | - nums2 : [1] 38 | - n : 1 39 | 40 | 41 | 所以要判断m和n是不是仍然大于0, 但是m不需要了,因为我们本来就是要在nums1的基础上改,m如果还大于0的话我们不需要改nums1了,保留不变即可 42 | 43 | 44 | AC代码 45 | 46 | 47 | ```python 48 | class Solution: 49 | def merge(self, nums1, m, nums2, n): 50 | """ 51 | :type nums1: List[int] 52 | :type m: int 53 | :type nums2: List[int] 54 | :type n: int 55 | :rtype: void Do not return anything, modify nums1 in-place instead. 56 | """ 57 | while m > 0 and n > 0: 58 | if nums1[m-1] > nums2[n-1]: 59 | nums1[m+n-1] = nums1[m-1] 60 | m -= 1 61 | else: 62 | nums1[m+n-1] = nums2[n-1] 63 | n -= 1 64 | if n > 0: 65 | nums1[:n] = nums2[:n] 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /Misc/read/133._clone_graph.md: -------------------------------------------------------------------------------- 1 | ###133. Clone Graph 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | Medium 10 | 11 | 12 | 13 | 思路: 14 | 15 | DFS或者BFS把graph traverse一遍,边traverse边复制。因为nodes are labeled uniquely,这就是方便的地方,但是注意node可能重复和有self-loop. 16 | 17 | 所以先建立新的root node,然后有一个dict把node label和node一一对应。 18 | 19 | 用stack来存储原本的graph root node,对原本的graph做DFS,这个时候,如果这个node的neighbor是已经出现过,那么我们就是去修改原本的existNode,让它指向存在的neighbor,否则创建新的,再把它们联系起来,谷歌了一下,别人写的比我更简单。anyway,先AC。 20 | 21 | 22 | 23 | `if cur.label in createdNodes:`多余。 24 | 25 | 26 | 27 | 28 | ``` 29 | class Solution(object): 30 | def cloneGraph(self, node): 31 | """ 32 | :type node: UndirectedGraphNode 33 | :rtype: UndirectedGraphNode 34 | """ 35 | if node == None: return None 36 | 37 | root = UndirectedGraphNode(node.label) 38 | # must 1 to 1 39 | createdNodes = {} 40 | createdNodes[root.label] = root 41 | 42 | stack = [] 43 | stack.append(node) 44 | 45 | while stack: 46 | cur = stack.pop() 47 | if cur.label in createdNodes: 48 | existNode = createdNodes[cur.label] 49 | for neighbor in cur.neighbors: 50 | if neighbor.label in createdNodes: 51 | existNeighbor = createdNodes[neighbor.label] 52 | existNode.neighbors.append(existNeighbor) 53 | else: 54 | newNode = UndirectedGraphNode(neighbor.label) 55 | existNode.neighbors.append(newNode) 56 | createdNodes[neighbor.label] = newNode 57 | stack.append(neighbor) 58 | return root 59 | ``` 60 | 61 | 62 | 63 | 看了别人的代码,貌似比我又写的简洁。 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Misc/read/151._reverse_words_in_a_string.md: -------------------------------------------------------------------------------- 1 | ### 151. Reverse Words in a String 2 | 3 | 题目: 4 | 5 | 6 | 难度: 7 | Medium 8 | 9 | 太简单了 10 | 11 | ```python 12 | class Solution(object): 13 | def reverseWords(self, s): 14 | """ 15 | :type s: str 16 | :rtype: str 17 | """ 18 | tmp = s.split() 19 | res = " ".join(tmp[::-1]) 20 | return res 21 | ``` 22 | 23 | ```python 24 | class Solution(object): 25 | def reverseWords(self, s): 26 | """ 27 | :type s: str 28 | :rtype: str 29 | """ 30 | tmp = s.split() 31 | tmp.reverse() 32 | res = " ".join(tmp) 33 | return res 34 | ``` 35 | -------------------------------------------------------------------------------- /Misc/read/168._excel_sheet_column_title.md: -------------------------------------------------------------------------------- 1 | ###168. Excel Sheet Column Title 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 依旧26进制的反击,不过这个反击我做的没之前那个好,看了hint 13 | 14 | ``` 15 | class Solution(object): 16 | def convertToTitle(self, n): 17 | """ 18 | :type n: int 19 | :rtype: str 20 | """ 21 | ans = '' 22 | while n : 23 | ans = chr(ord('A') + (n - 1) % 26) + ans 24 | n = (n - 1) // 26 25 | return ans 26 | 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /Misc/read/169._majority_element.md: -------------------------------------------------------------------------------- 1 | ###169. Majority Element 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 思路: 13 | 14 | 其实这个我有点有想到过 15 | 16 | 17 | 给定一个长度为 n的数组,其中有一个数,它出现的次数大于⎣n/2⎦,称为主要元素,找到它. 18 | 19 | 这个很像之前做过的一道CLRS的题目,想法可以用divide & conquer. 20 | 21 | 22 | - 如果数组长度 <= 2,那么return第一个即解决问题 23 | - 如果长度 > 2,那么可以两两配对,对于配对一样的结果,删去 24 | - 如果最后余一个,这一个留下 25 | - shuffle之后再尝试两两配对,直到最后结果不再改变 26 | 27 | 这样肯定是能解决问题的,因为为了满足次数大于⎣n/2⎦这个条件。 28 | 29 | 30 | 31 | 32 | 33 | 34 | ``` 35 | 36 | 1 2 1 2 1 2 1 2 37 | 2 3 2 3 2 3 2 3 38 | 2 4 2 2 2 2 3 39 | 2 4 2 3 3 40 | 3 2 41 | 2 2 42 | 2 2 43 | ``` 44 | 45 | 思路容易implement非常难啊. 46 | 47 | 48 | 49 | 这个问题有一个很出名的算法 50 | 51 | 52 | Boyer-Moore众数(majority number) 问题 53 | 54 | 在数组中找到两个不相同的元素并删除它们,不断重复此过程,直到数组中元素都相同,那么剩下的元素就是主要元素。 55 | 56 | 57 | 这个算法的妙处在于不直接删除数组中的元素,而是利用一个计数变量. 58 | 59 | 伪码 60 | 61 | def majorityElement(self, nums): 62 | count,major=0,0 63 | for n in nums: 64 | if count==0: 65 | major=n 66 | if major==n: 67 | count+=1 68 | else: 69 | count-=1 70 | return major 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Misc/read/171._excel_sheet_column_number.md: -------------------------------------------------------------------------------- 1 | ###171. Excel Sheet Column Number 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 26进制的反击 14 | 15 | ``` 16 | class Solution(object): 17 | def titleToNumber(self, s): 18 | """ 19 | :type s: str 20 | :rtype: int 21 | """ 22 | maps = {} 23 | for i in range(65,91): 24 | maps[chr(i)] = i - 64 25 | 26 | lst = list(s) 27 | lst.reverse() 28 | num = 0 29 | for idx,item in enumerate(lst): 30 | num += maps[item] * (26 ** idx) 31 | return num 32 | 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /Misc/read/172._Factorial_Trailing_Zeroes.md: -------------------------------------------------------------------------------- 1 | # 172. Factorial Trailing Zeroes 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/factorial-trailing-zeroes/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an integer n, return the number of trailing zeroes in n!. 15 | 16 | Example 1: 17 | 18 | Input: 3 19 | Output: 0 20 | Explanation: 3! = 6, no trailing zero. 21 | Example 2: 22 | 23 | Input: 5 24 | Output: 1 25 | Explanation: 5! = 120, one trailing zero. 26 | Note: Your solution should be in logarithmic time complexity. 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | ******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)****** 33 | 34 | 思路就是开始看我们有多少个5,多少个25,多少个125,这些数字成为base,直到这个base比我们的n大了,我们就不继续加了。那这是为什么呢? 35 | 36 | 因为我们知道想让后面多个0,那一定要是偶数乘以5的形式,我们知道偶数一定是比5多的,所以完全够用,所以直接一直加就行了。 37 | 38 | 39 | 开始我还想复杂了,每次算出最前的base_val,即1有0个0,5有1个0,25有6个0,我是通过算出所在区间然后再叠加,这样显然可以, 40 | 但是不如上面的想法来得直接来得快。 41 | 42 | 前后想了一个小时,真蠢啊!!! 43 | 44 | ```python 45 | class Solution(object): 46 | def trailingZeroes(self, n): 47 | """ 48 | :type n: int 49 | :rtype: int 50 | """ 51 | base, res = 5, 0 52 | while n >= base: 53 | res += n // base 54 | base *= 5 55 | return res 56 | ``` 57 | 58 | 59 | -------------------------------------------------------------------------------- /Misc/read/179._Largest_Number.md: -------------------------------------------------------------------------------- 1 | ### 179. Largest Number 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Medium 10 | 11 | 12 | 思路 13 | 14 | 先排序,再合并,若最后为空字符串,则返回'0' 15 | 16 | 其中排序思想为字符串的经典比较: 17 | ``` 18 | """ 19 | Replacement for built-in funciton cmp that was removed in Python 3 20 | 21 | Compare the two objects x and y and return an integer according to 22 | the outcome. The return value is negative if x < y, zero if x == y 23 | and strictly positive if x > y. 24 | """ 25 | ``` 26 | 27 | ```python 28 | class Solution(object): 29 | def largestNumber(self, nums): 30 | """ 31 | :type nums: List[int] 32 | :rtype: str 33 | """ 34 | nums = [str(num) for num in nums] 35 | nums.sort(cmp=lambda x, y: cmp(y+x, x+y)) 36 | return ''.join(nums).lstrip('0') if ''.join(num).lstrip('0') else '0' 37 | ``` 38 | 或者更简单一点 39 | 40 | ```python 41 | class Solution(object): 42 | def largestNumber(self, nums): 43 | """ 44 | :type nums: List[int] 45 | :rtype: str 46 | """ 47 | nums = [str(num) for num in nums] 48 | nums.sort(cmp=lambda x, y: cmp(y+x, x+y)) 49 | return ''.join(nums).lstrip('0') or '0' 50 | ``` 51 | 52 | -------------------------------------------------------------------------------- /Misc/read/189._rotate_array.md: -------------------------------------------------------------------------------- 1 | ###189. Rotate Array 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 首先,要知道一点,```k```如果大于```nums```的长度了,那么其实进行 ```k % len(nums)``` 次就行了 10 | 11 | 其次,要注意```k 为0```的情况 12 | 13 | ```python 14 | class Solution(object): 15 | def rotate(self, nums, k): 16 | """ 17 | :type nums: List[int] 18 | :type k: int 19 | :rtype: void Do not return anything, modify nums in-place instead. 20 | """ 21 | k = k % len(nums) 22 | if k != 0: 23 | tmp = nums[-k:] 24 | for j in range(len(nums)-1, k-1, -1): 25 | nums[j] = nums[j-k] 26 | nums[:k] = tmp 27 | ``` 28 | 29 | 30 | 还有作弊大法,贼🐂批 31 | 32 | ```python 33 | class Solution(object): 34 | def rotate(self, nums, k): 35 | """ 36 | :type nums: List[int] 37 | :type k: int 38 | :rtype: void Do not return anything, modify nums in-place instead. 39 | """ 40 | k %= len(nums) 41 | nums[:] = nums[-k:] + nums[:-k] 42 | ``` 43 | -------------------------------------------------------------------------------- /Misc/read/204._count_primes.md: -------------------------------------------------------------------------------- 1 | ###204. Count Primes 2 | 3 | 4 | 题目: 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 14 | 这个题的hint是已经把算法喂到嘴边了 15 | 16 | 17 | 18 | 19 | ``` 20 | Input: an integer n > 1 21 | 22 | Let A be an array of Boolean values, indexed by integers 2 to n, 23 | initially all set to true. 24 | 25 | for i = 2, 3, 4, ..., not exceeding √n: 26 | if A[i] is true: 27 | for j = i^2, i^2+i, i^2+2*i, i^2+3i, ..., not exceeding n : 28 | A[j] := false 29 | 30 | Output: all i such that A[i] is true. 31 | ``` 32 | 33 | 34 | 35 | python算法 36 | 37 | 38 | ``` 39 | class Solution(object): 40 | def countPrimes(self, n): 41 | """ 42 | :type n: int 43 | :rtype: int 44 | """ 45 | isPrime = [1 for i in range(n)] 46 | 47 | i = 2 48 | while i * i < n: 49 | if isPrime[i]: 50 | j = i * i 51 | while j < n : 52 | isPrime[j] = 0 53 | j += i 54 | i += 1 55 | 56 | return sum(isPrime[2:]) 57 | ``` -------------------------------------------------------------------------------- /Misc/read/205._isomorphic_strings.md: -------------------------------------------------------------------------------- 1 | ###205. Isomorphic Strings 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 10 | AC之法,用dictionary,因为限制,所以确保s 和 t 是isomorphic 同时 t 和 s 是 11 | 12 | 13 | ``` 14 | class Solution(object): 15 | def isIsomorphic(self, s, t): 16 | """ 17 | :type s: str 18 | :type t: str 19 | :rtype: bool 20 | """ 21 | return self.iso(s,t) and self.iso(t,s) 22 | 23 | def iso(self,s, t): 24 | """ 25 | :type s: str 26 | :type t: str 27 | :rtype: bool 28 | """ 29 | mapx = {} 30 | for i in range(len(s)): 31 | if s[i] not in mapx: 32 | mapx[s[i]] = t[i] 33 | elif s[i] in mapx: 34 | if t[i] != mapx[s[i]]: 35 | return False 36 | return True 37 | 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /Misc/read/223._rectangle_area.md: -------------------------------------------------------------------------------- 1 | # 223. Rectangle Area 2 | **难度: 中等** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/rectangle-area/description/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | Find the total area covered by two rectilinear rectangles in a 2D plane. 14 | 15 | Each rectangle is defined by its bottom left corner and top right corner as shown in the figure. 16 | 17 | Rectangle Area 18 | 19 | Example: 20 | 21 | Input: A = -3, B = 0, C = 3, D = 4, E = 0, F = -1, G = 9, H = 2 22 | Output: 45 23 | Note: 24 | 25 | Assume that the total area is never beyond the maximum possible value of int. 26 | ``` 27 | 28 | ## 解题方案 29 | 30 | > 思路 1 31 | 32 | sb题没什么好说的 33 | 34 | ```python 35 | class Solution(object): 36 | def computeArea(self, A, B, C, D, E, F, G, H): 37 | """ 38 | :type A: int 39 | :type B: int 40 | :type C: int 41 | :type D: int 42 | :type E: int 43 | :type F: int 44 | :type G: int 45 | :type H: int 46 | :rtype: int 47 | """ 48 | return (C - A) * (D - B) + (H - F) * (G - E) - max(min(C, G) - max(A, E), 0) * max(min(D, H) - max(B, F), 0) 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /Misc/read/228._summary_ranges.md: -------------------------------------------------------------------------------- 1 | ### 228. Summary Ranges 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Medium 10 | 11 | 12 | Just collect the ranges, then format and return them. 13 | 14 | ```python 15 | class Solution(object): 16 | def summaryRanges(self, nums): 17 | """ 18 | :type nums: List[int] 19 | :rtype: List[str] 20 | """ 21 | ranges = [] 22 | for i in nums: 23 | if not ranges or i > ranges[-1][-1] + 1: 24 | ranges += [], 25 | ranges[-1][1:] = i, 26 | return ['->'.join(map(str, r)) for r in ranges] 27 | ``` 28 | About the commas :-) 29 | 30 | ``` 31 | ranges += [], 32 | r[1:] = n, 33 | ``` 34 | Why the trailing commas? Because it turns the right hand side into a tuple and I get the same effects as these more common alternatives: 35 | ``` 36 | ranges += [[]] 37 | or 38 | ranges.append([]) 39 | 40 | r[1:] = [n] 41 | ``` 42 | Without the comma, … 43 | 44 | - ranges += [] wouldn’t add [] itself but only its elements, i.e., nothing. 45 | - r[1:] = n wouldn’t work, because my n is not an iterable. 46 | 47 | Why do it this way instead of the more common alternatives I showed above? Because it’s shorter and faster (according to tests I did a while back). 48 | 49 | 写到这里可能又有疑问了🤔️,为什么不可以直接写```ranges[-1][1] = i```呢,当然是会报```IndexError: list assignment index out of range```错误啦,那为什么```ranges[-1][1:] = i,```可以呢? 50 | 51 | 简单来说 52 | 53 | L1=L 与 L1=L[:] 54 | - L1和L 都是对同一个对象的引用(所谓绑定的意思)。 55 | - L[:] 是生成了一个和L不同的新的对象,L1 变为了L[:] 这个对象的引用。 56 | 57 | 58 | 参考[stefan](https://leetcode.com/problems/summary-ranges/discuss/63193) 59 | -------------------------------------------------------------------------------- /Misc/read/229._majority_element_ii.md: -------------------------------------------------------------------------------- 1 | ###229. Majority Element II 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Medium 11 | 12 | 思路: 13 | 14 | majority element是两两比较扔掉不同的元素,然后最后会留下一个。 15 | 16 | 这里变成三三比较来扔东西, find all elements that appear more than ⌊ n/3 ⌋ times,所以最多可以有两个majority element ii. 17 | 18 | 19 | 最后再加一个比较来确认这些函数是majority element 20 | 21 | ``` 22 | class Solution(object): 23 | def majorityElement(self, nums): 24 | """ 25 | :type nums: List[int] 26 | :rtype: List[int] 27 | """ 28 | cnt1 = 0 29 | cnt2 = 0 30 | maj1 = 0 31 | maj2 = 0 32 | for num in nums: 33 | if maj1 == num: 34 | cnt1 += 1 35 | elif maj2 == num: 36 | cnt2 += 1 37 | elif cnt1 == 0: 38 | maj1 = num 39 | cnt1 += 1 40 | elif cnt2 == 0: 41 | maj2 = num 42 | cnt2 += 1 43 | else: 44 | cnt1 -= 1 45 | cnt2 -= 1 46 | 47 | cnt1 = 0 48 | cnt2 = 0 49 | 50 | n = len(nums) 51 | res = [] 52 | for num in nums: 53 | if maj1 == num: 54 | cnt1 += 1 55 | elif maj2 == num: 56 | cnt2 += 1 57 | if cnt1 > n/3: 58 | res.append(maj1) 59 | if cnt2 > n/3: 60 | res.append(maj2) 61 | return res 62 | ``` -------------------------------------------------------------------------------- /Misc/read/242._valid_anagram.md: -------------------------------------------------------------------------------- 1 | ### 242. Valid Anagram 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度 : Easy 8 | 9 | 10 | 一行瞬秒: 11 | 12 | ```python 13 | class Solution(object): 14 | def isAnagram(self, s, t): 15 | """ 16 | :type s: str 17 | :type t: str 18 | :rtype: bool 19 | """ 20 | return collections.Counter(s) == collections.Counter(t) 21 | ``` 22 | 23 | ```python 24 | class Solution(object): 25 | def isAnagram(self, s, t): 26 | """ 27 | :type s: str 28 | :type t: str 29 | :rtype: bool 30 | """ 31 | return sorted(s) == sorted(t) 32 | 33 | ``` 34 | 35 | 36 | 用字数统计,因为只可能是26个字母 37 | 38 | 39 | ``` 40 | 41 | class Solution(object): 42 | def isAnagram(self, s, t): 43 | """ 44 | :type s: str 45 | :type t: str 46 | :rtype: bool 47 | """ 48 | if len(s) != len(t): 49 | return False 50 | 51 | charCnt = [0] * 26 52 | 53 | for i in range(len(s)): 54 | charCnt[ord(s[i]) - 97] += 1 55 | charCnt[ord(t[i]) - 97] -= 1 56 | 57 | for cnt in charCnt: 58 | if cnt != 0: 59 | return False 60 | return True 61 | ``` 62 | -------------------------------------------------------------------------------- /Misc/read/258_ Add_Digits.md: -------------------------------------------------------------------------------- 1 | ### 258. Add Digits 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 思路 13 | 14 | 这就简单的一p了。。 15 | 16 | 17 | ```python 18 | class Solution(object): 19 | def addDigits(self, num): 20 | """ 21 | :type num: int 22 | :rtype: int 23 | """ 24 | while num / 10 >= 1: 25 | tmp = 0 26 | while num / 10 >= 1: 27 | tmp += num % 10 28 | num /= 10 29 | tmp += num % 10 30 | num = tmp 31 | return num 32 | ``` 33 | 34 | 35 | -------------------------------------------------------------------------------- /Premium/159._Longest_Substring_with_At_Most_Two_Distinct_Characters.md: -------------------------------------------------------------------------------- 1 | # 159. Longest Substring with At Most Two Distinct Characters 2 | 3 | **难度: Hard** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a string s , find the length of the longest substring t that contains at most 2 distinct characters. 15 | 16 | Example 1: 17 | 18 | Input: "eceba" 19 | Output: 3 20 | Explanation: t is "ece" which its length is 3. 21 | Example 2: 22 | 23 | Input: "ccaabbb" 24 | Output: 5 25 | Explanation: t is "aabbb" which its length is 5. 26 | ``` 27 | 28 | ## 解题方案 29 | 30 | > 思路 1 31 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 32 | 33 | 34 | ```python 35 | class Solution(object): 36 | def lengthOfLongestSubstringTwoDistinct(self, s): 37 | """ 38 | :type s: str 39 | :rtype: int 40 | """ 41 | maps = {} 42 | begin, end, counter, length = 0, 0, 0, 0 43 | while end < len(s): 44 | maps[s[end]] = maps.get(s[end], 0) + 1 45 | if maps[s[end]] == 1: 46 | counter += 1 47 |            end += 1   # end 永远指向下一个待处理的字符 48 |            while counter > 2: 49 | maps[s[begin]] -= 1 50 | if maps[s[begin]] == 0: 51 | counter -= 1 52 | begin += 1 53 |            length = max(length, end - begin) # 因此这里是```end - begin```而不是```end - begin + 1``` 54 |        return length 55 | ``` 56 | 57 | 58 | -------------------------------------------------------------------------------- /Premium/176._Second_Highest_Salary.md: -------------------------------------------------------------------------------- 1 | # 176. Second Highest Salary 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/second-highest-salary/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Write a SQL query to get the second highest salary from the Employee table. 15 | 16 | +----+--------+ 17 | | Id | Salary | 18 | +----+--------+ 19 | | 1 | 100 | 20 | | 2 | 200 | 21 | | 3 | 300 | 22 | +----+--------+ 23 | For example, given the above Employee table, the query should return 200 as the second highest salary. If there is no second highest salary, then the query should return null. 24 | 25 | +---------------------+ 26 | | SecondHighestSalary | 27 | +---------------------+ 28 | | 200 | 29 | +---------------------+ 30 | ``` 31 | 32 | ## 解题方案 33 | 34 | > 思路 1 35 | 36 | ```sql 37 | select Salary SecondHighestSalary from Employee 38 | union 39 | select null 40 | order by SecondHighestSalary desc limit 1, 1 41 | ``` 42 | 43 | 44 | > 思路 2 45 | 46 | ```sql 47 | select ( 48 | select distinct Salary from Employee order by Salary Desc limit 1, 1 49 | )as SecondHighestSalary 50 | ``` 51 | -------------------------------------------------------------------------------- /Premium/182._duplicate_emails.md: -------------------------------------------------------------------------------- 1 | # 182. duplicate-emails 查找重复的电子邮箱 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/duplicate-emails 10 | * https://leetcode-cn.com/problems/duplicate-emails/description 11 | 12 | > 内容描述 13 | 14 | ``` 15 | 编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。 16 | 17 | 示例: 18 | +----+---------+ 19 | | Id | Email | 20 | +----+---------+ 21 | | 1 | a@b.com | 22 | | 2 | c@d.com | 23 | | 3 | a@b.com | 24 | +----+---------+ 25 | 26 | 根据以上输入,你的查询应返回以下结果: 27 | +---------+ 28 | | Email | 29 | +---------+ 30 | | a@b.com | 31 | +---------+ 32 | 33 | 说明:所有电子邮箱都是小写字母。 34 | ``` 35 | 36 | ## 解题方案 37 | 38 | > 思路 1 39 | 40 | ```sql 41 | select Email 42 | from Person 43 | group by Email 44 | having count(1)>1 45 | ``` 46 | 或者 47 | ```sql 48 | select Email from Person group by Email having count(Email) > 1 49 | ``` 50 | -------------------------------------------------------------------------------- /Premium/249._Group_Shifted_Strings.md: -------------------------------------------------------------------------------- 1 | # 249. Group Shifted Strings 2 | **难度: 中等** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/group-shifted-strings/description/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". We can keep "shifting" which forms the sequence: 14 | 15 | "abc" -> "bcd" -> ... -> "xyz" 16 | Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence. 17 | 18 | Example: 19 | 20 | Input: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"], 21 | Output: 22 | [ 23 | ["abc","bcd","xyz"], 24 | ["az","ba"], 25 | ["acef"], 26 | ["a","z"] 27 | ] 28 | ``` 29 | 30 | ## 解题方案 31 | 32 | > 思路 1 33 | 34 | hash table存储pattern 35 | 36 | ```python 37 | class Solution(object): 38 | def groupStrings(self, strings): 39 | """ 40 | :type strings: List[str] 41 | :rtype: List[List[str]] 42 | """ 43 | table = {} 44 | for w in strings: 45 | pattern = '' 46 | for i in range(1, len(w)): 47 | if ord(w[i]) - ord(w[i - 1]) >= 0: 48 | pattern += str(ord(w[i]) - ord(w[i - 1])) 49 | else: 50 | pattern += str(ord(w[i]) - ord(w[i - 1]) + 26) ## 这是为了处理'az'和'ba'的情况 51 | 52 | if pattern in table: 53 | table[pattern].append(w) 54 | else: 55 | table[pattern] = [w] 56 | return [table[pattern] for pattern in table] 57 | ``` 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Premium/251._Flatten_2D_Vector.md: -------------------------------------------------------------------------------- 1 | # 251. Flatten 2D Vector 2 | 3 | **难度: Medium** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/flatten-2d-vector/discuss/67653/My-Python-Solution 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Implement an iterator to flatten a 2d vector. 15 | 16 | Example: 17 | 18 | Input: 2d vector = 19 | [ 20 | [1,2], 21 | [3], 22 | [4,5,6] 23 | ] 24 | Output: [1,2,3,4,5,6] 25 | Explanation: By calling next repeatedly until hasNext returns false, 26 | the order of elements returned by next should be: [1,2,3,4,5,6]. 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | 33 | 34 | ```python 35 | class Vector2D(object): 36 | 37 | def __init__(self, vec2d): 38 | """ 39 | Initialize your data structure here. 40 | :type vec2d: List[List[int]] 41 | """ 42 | self.row = 0 43 | self.col = 0 44 | self.vec = vec2d 45 | 46 | 47 | def next(self): 48 | """ 49 | :rtype: int 50 | """ 51 | res = self.vec[self.row][self.col] 52 | self.col += 1 53 | return res 54 | 55 | 56 | def hasNext(self): 57 | """ 58 | :rtype: bool 59 | """ 60 | while self.row < len(self.vec): 61 | if self.col < len(self.vec[self.row]): 62 | return True 63 | self.col = 0 64 | self.row += 1 65 | return False 66 | 67 | 68 | # Your Vector2D object will be instantiated and called as such: 69 | # i, v = Vector2D(vec2d), [] 70 | # while i.hasNext(): v.append(i.next()) 71 | ``` 72 | -------------------------------------------------------------------------------- /Premium/252._Meeting_Rooms.md: -------------------------------------------------------------------------------- 1 | # 252. Meeting Rooms 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/meeting-rooms/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings. 15 | 16 | Example 1: 17 | 18 | Input: [[0,30],[5,10],[15,20]] 19 | Output: false 20 | Example 2: 21 | 22 | Input: [[7,10],[2,4]] 23 | Output: true 24 | ``` 25 | 26 | ## 解题方案 27 | 28 | > 思路 1 29 | 30 | 31 | 排个序然后看看后面meeting的start会不会比前面meeting的end小,如果有立刻就返回False,全都没有那就返回True 32 | 33 | 34 | 35 | 36 | ```python 37 | class Solution(object): 38 | def canAttendMeetings(self, intervals): 39 | """ 40 | :type intervals: List[Interval] 41 | :rtype: bool 42 | """ 43 | if not intervals or len(intervals) < 2: 44 | return True 45 | intervals = sorted(intervals, key=lambda x:(x.start, x.end)) 46 | for i in range(1, len(intervals)): 47 | if intervals[i].start < intervals[i-1].end: 48 | return False 49 | return True 50 | ``` 51 | -------------------------------------------------------------------------------- /Premium/256. Paint House.md: -------------------------------------------------------------------------------- 1 | ### 256. Paint House 2 | 3 | 题目: 4 | 5 | 6 | 难度: 7 | Medium 8 | 9 | 10 | 11 | 其实这个题目有实际意义诶,至少我的故乡?在要申请啥东西的时候就把街上的房子全刷了。 12 | 13 | 然后这个是相邻的房子不同色。 14 | 15 | 16 | 17 | 其实我觉得paint fense更难一点 18 | 19 | 20 | 21 | 思路: 22 | 23 | 数组 dp\[x][3] 代表第x个房子paint r/g/b的值 24 | 25 | 26 | 27 | AC代码 28 | 29 | ``` 30 | class Solution(object): 31 | def minCost(self, costs): 32 | """ 33 | :type costs: List[List[int]] 34 | :rtype: int 35 | """ 36 | m = len(costs) 37 | if m == 0 : return 0 38 | elif m == 1 : return min(costs[0][0], costs[0][1],costs[0][2]) 39 | else: 40 | n = 3 if m else 0 41 | dp = [[0 for i in range(3)] for j in range(m)] 42 | 43 | dp[0] = costs[0] 44 | 45 | 46 | for i in range(1,m): 47 | dp[i][0] = min(dp[i-1][1],dp[i-1][2]) + costs[i][0] 48 | dp[i][1] = min(dp[i-1][0],dp[i-1][2]) + costs[i][1] 49 | dp[i][2] = min(dp[i-1][0],dp[i-1][1]) + costs[i][2] 50 | return min(dp[m-1][0], dp[m-1][1], dp[m-1][2]) 51 | 52 | ``` 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Stack-Queue-Heap-Sort-Graph/read/225._implement_stack_using_queues.md: -------------------------------------------------------------------------------- 1 | ###225. Implement Stack using Queues 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 又到了作弊神预言Python的强项 14 | 15 | 16 | ``` 17 | class Stack(object): 18 | def __init__(self): 19 | """ 20 | initialize your data structure here. 21 | """ 22 | self.lst = [] 23 | 24 | 25 | def push(self, x): 26 | """ 27 | :type x: int 28 | :rtype: nothing 29 | """ 30 | self.lst.append(x) 31 | 32 | 33 | def pop(self): 34 | """ 35 | :rtype: nothing 36 | """ 37 | self.lst.remove(self.lst[-1]) 38 | 39 | 40 | def top(self): 41 | """ 42 | :rtype: int 43 | """ 44 | return self.lst[-1] 45 | 46 | def empty(self): 47 | """ 48 | :rtype: bool 49 | """ 50 | return self.lst == [] 51 | 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /Stack-Queue-Heap-Sort-Graph/read/232._implement_queue_using_stacks.md: -------------------------------------------------------------------------------- 1 | ###232. Implement Queue using Stacks 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Easy 9 | 10 | 这个题没有乖乖听话,不过因为当年做过用两个stack来模拟queue 11 | 12 | 然后不得不说,我Python大法实在太厉害了 13 | 14 | 这功能强大的,我简直要啧啧啧 15 | 16 | ``` 17 | class Queue(object): 18 | def __init__(self): 19 | """ 20 | initialize your data structure here. 21 | """ 22 | self.lst = [] 23 | 24 | 25 | def push(self, x): 26 | """ 27 | :type x: int 28 | :rtype: nothing 29 | """ 30 | self.lst.append(x) 31 | 32 | 33 | def pop(self): 34 | """ 35 | :rtype: nothing 36 | """ 37 | del self.lst[0] 38 | 39 | def peek(self): 40 | """ 41 | :rtype: int 42 | """ 43 | return self.lst[0] 44 | 45 | 46 | def empty(self): 47 | """ 48 | :rtype: bool 49 | """ 50 | return self.lst == [] 51 | ``` -------------------------------------------------------------------------------- /Summary/Introduction to String Searching Algorithms – topcoder.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Summary/Introduction to String Searching Algorithms – topcoder.pdf -------------------------------------------------------------------------------- /Summary/Maximal Square.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Summary/Maximal Square.pdf -------------------------------------------------------------------------------- /Summary/Range Sum Query 2D - Immutable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Summary/Range Sum Query 2D - Immutable.pdf -------------------------------------------------------------------------------- /Summary/read/Binary Search.md: -------------------------------------------------------------------------------- 1 | ### Binary Search 2 | 3 | 4 | ```python 5 | def binarySearch(nums, target): 6 | l, r = 0, len(nums) -1 7 | while l <= r: 8 | mid = l + ((r-l) >> 1) 9 | if nums[mid] > target: 10 | r = mid - 1 11 | elif nums[mid] < target: 12 | l = mid + 1 13 | else: 14 | return mid 15 | return -1 16 | ``` 17 | 18 | 19 | wisdompeak大佬说, 20 | 21 | 标准模板就两套: 22 | ``` 23 | while (left>:右移 28 | 29 | ​ 30 | 31 | Bit Facts and Tricks 32 | 33 | ``` 34 | x ^ 0s = x x & 0s = 0 x | 0s = x 35 | x ^ 1s = ~x x & 1s = x x | 1s = 1s 36 | x ^ x = 0 x & x = x x | x = x 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /Summary/组合问题.md: -------------------------------------------------------------------------------- 1 | ### 组合问题 2 | 3 | 4 | #### 77.Combinations 5 | 6 | 7 | ##### 会超时的recursion 8 | 9 | 10 | 11 | ``` 12 | class Solution(object): 13 | def combine(self, n, k): 14 | """ 15 | :type n: int 16 | :type k: int 17 | :rtype: List[List[int]] 18 | """ 19 | ans = [] 20 | self.dfs(n, k, 1, [], ans) 21 | return ans 22 | 23 | def dfs(self, n, k ,start, lst, ans): 24 | if k == 0 : 25 | ans.append(lst) 26 | return 27 | for i in range(start, n+1): 28 | self.dfs(n, k - 1, i + 1,lst +[i], ans) 29 | ``` 30 | 31 | 理解方式 32 | 33 | ``` 34 | 35 | 1 2 3 36 | 12 13 14 23 24 34 37 | ``` 38 | 39 | 可以参照这里 40 | 41 | 42 | 43 | 44 | 45 | ##### 市面上流行解法 46 | 47 | 递归的思想: n选k 48 | 49 | - 如果 k==n ,则全选。 50 | - n > k 又可以分成两类: 51 | - 选了n, 则在余下的n-1中选k-1 52 | - 没有选n, 则在余下的n-1中选k 53 | 54 | 注意一下会有两个base case,因为k在不断减小和n在不断减小,所以写起来可以这样: 55 | 56 | 57 | ``` 58 | def combine(n,k): 59 | if k == 1: 60 | return [[i+1] for i in range(n)] 61 | if n == k: 62 | return [range(1, k+1)] 63 | # choose n , not choose n 64 | return [r + [n] for r in combine(n-1,k-1)] + combine(n-1,k) 65 | 66 | 67 | print combine(20,16) 68 | ``` 69 | 70 | 71 | #### 39. Combination Sum 72 | 73 | 74 | 使用正常递归思路 75 | 76 | 77 | #### 40. Combination Sum II 78 | 79 | 重复做跳过处理 80 | 81 | #### 216. Combination Sum III 82 | 83 | 84 | #### 377. Combination Sum IV 85 | -------------------------------------------------------------------------------- /Summary/编程思路总结.md: -------------------------------------------------------------------------------- 1 | ## 1. OJ 基本条件 2 | 达尔大佬对刷leetcode和刷笔试题有几个建议: 3 | 4 | 1. 一般oj是有要求时间的,一般是1秒。后台判题系统都是单核单线程跑,机器性能不会太好。1秒能运行的基本操作个数的量级是10^6-10^7, 5 | 个别代码能跑到10^8,但很少见。这种情况下,看数据范围是可以大致了解到这个题目需要什么样子的时间复杂度。 6 | 比如说,n<=1000的数据范围,o(n^3)的代码就不要写了,浪费时间而已。写代码之前得先计算自己代码的复杂度,预估自己代码跑的速度,再动手。 7 | 2. 基本操作指的是逻辑和加减法,乘法比加减法慢得多,但在大复杂度的前提下,这种复杂度是可以忽略的。比如说,在一个算法o(n^3)中, 8 | 代码中一个两层嵌套循环o(n^2)就显得没什么优化意义了。优化代码主要优化算法复杂度,而那些,要不要用位运算代替除法啊, 9 | 或者两个一层循环要不要合并成一个一层循环啊,没有意义,不要纠结,同级复杂度,才有优化意义 10 | 3. 高级编程语言每个api都有自己的复杂度,在没有了解复杂度之前不建议使用那些api,最好自己实现,比如哈希表啊,堆啊, 11 | 什么语言都有实现,熟悉之前还是乖乖自己实现的好 12 | 4. 注意精度误差。。。比如开方,如果开方开的是一个整数,结果也是整数,最好写个二分,或者写个牛顿迭代求零点, 13 | 不要用内置函数sqrt,求出来是个浮点数,会有误差 14 | 15 | 16 | ## 2. 判断环 17 | - 看到链表中的环就想到快慢指针 18 | - 看到图中的环就想到并查集,wisdompeak大佬说:用union find确实是判断图是否成环的一个很好的手段。但是它更常用在无向图。 19 | 对于有向图,用并查集需要非常小心。这里的edge都是有向的,我觉得无脑用并查集会有风险。 20 | 我的总结是:union find唯一能用在有向图的地方,就是只有我们试图保证这张图是树的时候。 21 | -------------------------------------------------------------------------------- /Tree/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Tree/.DS_Store -------------------------------------------------------------------------------- /Tree/222._count_complete_tree_nodes.md: -------------------------------------------------------------------------------- 1 | ###222. Count Complete Tree Nodes 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 11 | 思路: 12 | 13 | 14 | 思路一: 超时,跟一般的树一样,递归的来数nodes数 15 | 16 | 17 | 18 | ``` 19 | class Solution(object): 20 | def countNodes(self, root): 21 | """ 22 | :type root: TreeNode 23 | :rtype: int 24 | """ 25 | if root == None: 26 | return 0 27 | if root.left == None and root.right == None: 28 | return 1 29 | return 1 + self.countNodes(root.left) + self.countNodes(root.right) 30 | ``` 31 | 32 | 33 | 思路二:既然说了是 complete binary tree,那么必然有特性可用,complete binary tree的特性是除了最后一层,之前的就是perfect tree. 34 | 35 | 36 | 所以寻找左子树的最左边的高度和右子树的最右边的node高度,如果相同就是perfect tree,高度2^h - 1, 否则递归的来看左子树和右子树 37 | 38 | 39 | ``` 40 | 41 | class Solution(object): 42 | def countNodes(self, root): 43 | """ 44 | :type root: TreeNode 45 | :rtype: int 46 | """ 47 | if root == None: 48 | return 0 49 | 50 | p, q = root,root 51 | 52 | leftHeight = 0 53 | rightHeight = 0 54 | 55 | while p: 56 | p = p.left 57 | leftHeight += 1 58 | 59 | while q: 60 | q = q.right 61 | rightHeight += 1 62 | 63 | if leftHeight == rightHeight: 64 | return (int)(math.pow(2,leftHeight) - 1) 65 | else: 66 | return 1 + self.countNodes(root.left) + self.countNodes(root.right) 67 | ``` -------------------------------------------------------------------------------- /Tree/257._binary_tree_paths.md: -------------------------------------------------------------------------------- 1 | # 257. Binary Tree Paths 2 | **难度: 简单** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/binary-tree-paths/description/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | Given a binary tree, return all root-to-leaf paths. 14 | 15 | Note: A leaf is a node with no children. 16 | 17 | Example: 18 | 19 | Input: 20 | 21 | 1 22 | / \ 23 | 2 3 24 | \ 25 | 5 26 | 27 | Output: ["1->2->5", "1->3"] 28 | 29 | Explanation: All root-to-leaf paths are: 1->2->5, 1->3 30 | ``` 31 | 32 | ## 解题方案 33 | 34 | > 思路 1 35 | 36 | 递归+DFS 37 | 38 | ```python 39 | class Solution(object): 40 | def binaryTreePaths(self, root): 41 | """ 42 | :type root: TreeNode 43 | :rtype: List[str] 44 | """ 45 | def helper(node, cur_path): 46 | if not node.left and not node.right: ## 到leaf了 47 | res.append(cur_path+[node.val]) 48 | return 49 | if node.left: 50 | helper(node.left, cur_path+[node.val]) 51 | if node.right: 52 | helper(node.right, cur_path+[node.val]) 53 | 54 | res = [] 55 | if not root: 56 | return res 57 | helper(root, []) 58 | 59 | return ['->'.join([str(val) for val in path]) for path in res] 60 | ``` 61 | 注意一点,很多人可能看到这里有好几次cur_path+[node.val],觉得干嘛不直接写在最开头了,事实是这样做的话cur_path就已经变化了,因为要执行完if node.left才去执行if node.right,此时cur_path就不是原来的cur_path了。 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Tree/261. Graph Valid Tree.md: -------------------------------------------------------------------------------- 1 | ### 261. Graph Valid Tree 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 10 | 难度 : Medium 11 | 12 | 13 | 14 | 思路: 15 | 16 | graph 为 tree 两个条件: 17 | 18 | - 这个图是connected 19 | - 没有cycle 20 | 21 | 22 | 23 | 偷懒AC代码,直接在323题,Number of Connected Components in an Undirected Graph上改的AC代码: 24 | 25 | 26 | 27 | ``` 28 | class Solution(object): 29 | def validTree(self, n, edges): 30 | """ 31 | :type n: int 32 | :type edges: List[List[int]] 33 | :rtype: bool 34 | """ 35 | def find(x): 36 | if uf[x] != x: 37 | uf[x] = find(uf[x]) 38 | return uf[x] 39 | 40 | def union(x,y): 41 | xRoot = find(x) 42 | yRoot = find(y) 43 | uf[xRoot] = yRoot 44 | 45 | uf = [i for i in range(n)] 46 | 47 | for node1, node2 in edges: 48 | # cycle exists 49 | if find(node1) == find(node2): 50 | print 'ha ' 51 | return False 52 | else: 53 | union(node1, node2) 54 | 55 | res = set() 56 | for i in range(n): 57 | res.add(find(i)) 58 | 59 | return len(res) == 1 60 | ``` 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Tree/366. Find Leaves of Binary Tree.md: -------------------------------------------------------------------------------- 1 | ### 366. Find Leaves of Binary Tree 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 10 | 11 | 难度 :Medium 12 | 13 | 14 | 15 | 按照它的要求,老老实实写了两个递归 findleaf 和 deleteleaf, 再组合起来 16 | 17 | 18 | 19 | AC代码 20 | 21 | ```python 22 | class Solution(object): 23 | def findLeaves(self, root): 24 | """ 25 | :type root: TreeNode 26 | :rtype: List[List[int]] 27 | """ 28 | def findLeaf(root): 29 | if not root: 30 | return [] 31 | elif not root.left and not root.right: 32 | return [root.val] 33 | else: 34 | return findLeaf(root.left) + findLeaf(root.right) 35 | def removeLeaf(root): 36 | if not root: 37 | return None 38 | elif not root.left and not root.right: 39 | return None 40 | else: 41 | if root.left: 42 | root.left = removeLeaf(root.left) 43 | if root.right: 44 | root.right = removeLeaf(root.right) 45 | return root 46 | res = [] 47 | while root: 48 | res.append(findLeaf(root)) 49 | root = removeLeaf(root) 50 | return res 51 | ``` 52 | 53 | -------------------------------------------------------------------------------- /Tree/404._sum_of_left_leaves.md: -------------------------------------------------------------------------------- 1 | ###404. Sum of Left Leaves 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 13 | 思路: 14 | 15 | 16 | 典型递归,检查root的左孩子是不是node,是的话加上它的值,不是的话递归去求它的孩子们的,对于右边,递归的求sum of left leaves 17 | 18 | 19 | 20 | ``` 21 | class Solution(object): 22 | def sumOfLeftLeaves(self, root): 23 | """ 24 | :type root: TreeNode 25 | :rtype: int 26 | """ 27 | def isLeaf(node): 28 | if node == None: 29 | return False 30 | if node.left == None and node.right == None: 31 | return True 32 | return False 33 | 34 | res = 0 35 | 36 | if root: 37 | if isLeaf(root.left): 38 | res += root.left.val 39 | else: 40 | res += self.sumOfLeftLeaves(root.left) 41 | if root.right: 42 | res += self.sumOfLeftLeaves(root.right) 43 | 44 | return res 45 | ``` -------------------------------------------------------------------------------- /Tree/437._path_sum_iii.md: -------------------------------------------------------------------------------- 1 | ### 437. Path Sum III 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | Easy 11 | 12 | 思路: 13 | 14 | 15 | 16 | 17 | ```python 18 | class Solution(object): 19 | def pathSum(self, root, sum): 20 | """ 21 | :type root: TreeNode 22 | :type sum: int 23 | :rtype: int 24 | """ 25 | if not root: 26 | return 0 27 | res = self.auxPathSum(root, sum) 28 | res += self.pathSum(root.left, sum) 29 | res += self.pathSum(root.right, sum) 30 | return res 31 | def auxPathSum(self, root, sum): 32 | if not root: 33 | return 0 34 | if sum == root.val: 35 |            # 因为可能有负值, 所以sum为0也会有解, 必须加上 36 |            return 1 + self.auxPathSum(root.left, 0) + self.auxPathSum(root.right, 0) 37 | else: 38 | return self.auxPathSum(root.left, sum - root.val) + self.auxPathSum(root.right, sum - root.val) 39 | ``` 40 | -------------------------------------------------------------------------------- /Tree/read/096._unique_binary_search_trees.md: -------------------------------------------------------------------------------- 1 | # 96. Unique Binary Search Trees 2 | **难度: 中等** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/unique-binary-search-trees/description/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? 14 | 15 | Example: 16 | 17 | Input: 3 18 | Output: 5 19 | Explanation: 20 | Given n = 3, there are a total of 5 unique BST's: 21 | 22 | 1 3 3 2 1 23 | \ / / / \ \ 24 | 3 2 1 1 3 2 25 | / / \ \ 26 | 2 1 2 3 27 | ``` 28 | 29 | ## 解题方案 30 | 31 | > 思路 1 32 | 33 | 34 | 参照此处hint: 35 | 36 | https://shenjie1993.gitbooks.io/leetcode-python/096%20Unique%20Binary%20Search%20Trees.html 37 | 38 | 39 | 首先明确n个不等的数它们能构成的二叉搜索树的种类都是相等的。而且1到n都可以作为二叉搜索树的根节点,当k是根节点时,它的左边有k-1个不等的数,它的右边有n-k个不等的数。以k为根节点的二叉搜索树的种类就是左右可能的种类的乘积。用递推式表示就是 h(n) = h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2) ,其中h(0)=h(1)=1,因为0个或者1个数能组成的形状都只有一个。从1到n依次算出h(x)的值即可。此外这其实就是一个卡特兰数,可以直接用数学公式计算,不过上面的方法更加直观一些。 40 | 41 | 42 | ```python 43 | class Solution(object): 44 | def numTrees(self, n): 45 | """ 46 | :type n: int 47 | :rtype: int 48 | """ 49 | dp = [1 for i in range(n+1)] 50 | for i in range(2, n+1): 51 | s = 0 52 | for k in range(i): 53 | s += dp[k]*dp[i-k-1] 54 | dp[i] = s 55 | return dp[-1] 56 | ``` 57 | -------------------------------------------------------------------------------- /Tree/read/100._same_tree.md: -------------------------------------------------------------------------------- 1 | ### 100. Same Tree 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 太简单了,递归一行! 14 | 15 | 16 | ```python 17 | # Definition for a binary tree node. 18 | # class TreeNode(object): 19 | # def __init__(self, x): 20 | # self.val = x 21 | # self.left = None 22 | # self.right = None 23 | 24 | class Solution(object): 25 | def isSameTree(self, p, q): 26 | """ 27 | :type p: TreeNode 28 | :type q: TreeNode 29 | :rtype: bool 30 | """ 31 | return p.val == q.val and all(map(self.isSameTree, (p.left, p.right), (q.left, q.right))) if p and q else p is q 32 | ``` 33 | 34 | ```python 35 | class Solution(object): 36 | def isSameTree(self, p, q): 37 | """ 38 | :type p: TreeNode 39 | :type q: TreeNode 40 | :rtype: bool 41 | """ 42 | if (not p and q) or (p and not q): 43 | return False 44 | if not p and not q: 45 | return True 46 | if p.val == q.val: 47 | return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 48 | return False 49 | ``` 50 | -------------------------------------------------------------------------------- /Tree/read/101._symmetric_tree.md: -------------------------------------------------------------------------------- 1 | ### 101. Symmetric Tree 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Easy 11 | 12 | 13 | 两棵树symmetric, 有几种可能: 14 | 15 | - 均为none,symmetric 16 | - 左孩子,右孩子都不存在,并且值相等,symmetric 17 | - 右子树和另一棵树的左子树相等,左子树和另一颗树的右子树相等 18 | 19 | ```python 20 | class Solution(object): 21 | def isSymmetric(self, root): 22 | """ 23 | :type root: TreeNode 24 | :rtype: bool 25 | """ 26 | if not root: 27 | return True 28 | return self.symmetric(root.left, root.right) 29 | 30 | def symmetric(self, l1, l2): 31 | if not l1 and not l2: 32 | return True 33 | if not l1 or not l2: 34 | return False 35 | if l1.val == l2.val: 36 | return self.symmetric(l1.left, l2.right) and self.symmetric(l1.right, l2.left) 37 | else: 38 | return False 39 | ``` 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Tree/read/103._binary_tree_zigzag_level_order_traversal.md: -------------------------------------------------------------------------------- 1 | ### 103. Binary Tree Zigzag Level Order Traversal 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 13 | 14 | ```python 15 | class Solution(object): 16 | def zigzagLevelOrder(self, root): 17 | """ 18 | :type root: TreeNode 19 | :rtype: List[List[int]] 20 | """ 21 | if not root: 22 | return [] 23 | res, cur_level, level_count = [], [root], 0 24 | while cur_level: 25 | next_level, tmp_res = [], [] 26 | for node in cur_level: 27 | tmp_res.append(node.val) 28 | if node.left: 29 | next_level.append(node.left) 30 | if node.right: 31 | next_level.append(node.right) 32 | if level_count % 2 == 0: 33 | res.append(tmp_res) 34 | else: 35 | tmp_res.reverse() 36 | res.append(tmp_res) 37 | level_count += 1 38 | cur_level = next_level 39 | 40 | return res 41 | ``` 42 | 43 | 44 | -------------------------------------------------------------------------------- /Tree/read/104._maximum_depth_of_binary_tree.md: -------------------------------------------------------------------------------- 1 | # 104. Maximum Depth of Binary Tree 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/maximum-depth-of-binary-tree/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a binary tree, find its maximum depth. 15 | 16 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 17 | 18 | Note: A leaf is a node with no children. 19 | 20 | Example: 21 | 22 | Given binary tree [3,9,20,null,null,15,7], 23 | 24 | 3 25 | / \ 26 | 9 20 27 | / \ 28 | 15 7 29 | return its depth = 3. 30 | ``` 31 | 32 | ## 解题方案 33 | 34 | > 思路 1 35 | ******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)****** 36 | 37 | 38 | 简单题,但是这道题跟[leetcode111](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/111._minimum_depth_of_binary_tree.md)不一样,这道题没有特殊情况,所以一行就够了 39 | 40 | 41 | ```python 42 | class Solution(object): 43 | def maxDepth(self, root): 44 | """ 45 | :type root: TreeNode 46 | :rtype: int 47 | """ 48 | return 1 + max(map(self.maxDepth, (root.left, root.right))) if root else 0 49 | ``` 50 | -------------------------------------------------------------------------------- /Tree/read/105._construct_binary_tree_from_preorder_and_inorder_traversal.md: -------------------------------------------------------------------------------- 1 | # 105. Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树 2 | 3 | **难度: 中等** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ 10 | * https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ 11 | 12 | > 内容描述 13 | 14 | ``` 15 | 根据一棵树的前序遍历与中序遍历构造二叉树。 16 | 17 | 注意: 18 | 你可以假设树中没有重复的元素。 19 | 20 | 例如,给出 21 | 22 | 前序遍历 preorder = [3,9,20,15,7] 23 | 中序遍历 inorder = [9,3,15,20,7] 24 | 返回如下的二叉树: 25 | 26 | 3 27 | / \ 28 | 9 20 29 | / \ 30 | 15 7 31 | ``` 32 | 33 | ## 解题方案 34 | 35 | > 思路 1 36 | 37 | 一句话,看到树🌲就要想到递归 38 | 39 | - preorder 是 根 -> 左 -> 右 40 | - inorder 是 左 -> 根 -> 右 41 | 42 | 首先pre的第一个就是整个树的root, 假设 preorder[0] = inorder[k],那么inorder的前k-1个就是树的左子树,后面部分就是树的右子树 43 | 44 | ```python 45 | class Solution(object): 46 | def buildTree(self, preorder, inorder): 47 | """ 48 | :type preorder: List[int] 49 | :type inorder: List[int] 50 | :rtype: TreeNode 51 | """ 52 | if not preorder or len(preorder) == 0: 53 | return None 54 | root = TreeNode(preorder[0]) 55 | k = inorder.index(preorder[0]) 56 | root.left = self.buildTree(preorder[1:k+1], inorder[0:k]) 57 | root.right = self.buildTree(preorder[k+1:], inorder[k+1:]) 58 | return root 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /Tree/read/107._binary_tree_level_order_traversal_ii.md: -------------------------------------------------------------------------------- 1 | # 107. Binary Tree Level Order Traversal II 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/binary-tree-level-order-traversal-ii/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). 15 | 16 | For example: 17 | Given binary tree [3,9,20,null,null,15,7], 18 | 3 19 | / \ 20 | 9 20 21 | / \ 22 | 15 7 23 | return its bottom-up level order traversal as: 24 | [ 25 | [15,7], 26 | [9,20], 27 | [3] 28 | ] 29 | ``` 30 | 31 | ## 解题方案 32 | 33 | > 思路 1 34 | ******- 时间复杂度: O(N)******- 空间复杂度: O(N)****** 35 | 36 | 37 | 用102 的算法作弊 38 | 39 | 40 | ```python 41 | class Solution: 42 | def levelOrderBottom(self, root): 43 | """ 44 | :type root: TreeNode 45 | :rtype: List[List[int]] 46 | """ 47 | def dfs(node, level, res): 48 | if not node: 49 | return 50 | if len(res) < level: 51 | res.append([]) 52 | res[level-1].append(node.val) 53 | dfs(node.left, level+1, res) 54 | dfs(node.right, level+1, res) 55 | 56 | res = [] 57 | dfs(root, 1, res) 58 | return res[::-1] 59 | ``` 60 | 61 | 62 | -------------------------------------------------------------------------------- /Tree/read/108._convert_sorted_array_to_binary_search_tree.md: -------------------------------------------------------------------------------- 1 | ### 108. Convert Sorted Array to Binary Search Tree 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | Medium 9 | 10 | 11 | 思路: 12 | 13 | 递归 14 | 15 | - nums为空,return None 16 | - nums非空,nums[n/2]为中间元素,根结点,nums[:mid]为左子树, nums[mid+1:]为右子树 17 | 18 | 19 | ```python 20 | class Solution(object): 21 | def sortedArrayToBST(self, nums): 22 | """ 23 | :type nums: List[int] 24 | :rtype: TreeNode 25 | """ 26 | if not nums: 27 | return None 28 | if nums: 29 | mid = len(nums) / 2 30 | root = TreeNode(nums[mid]) 31 | root.left = self.sortedArrayToBST(nums[:mid]) 32 | root.right = self.sortedArrayToBST(nums[mid+1:]) 33 | return root 34 | ``` 35 | -------------------------------------------------------------------------------- /Tree/read/109._convert_sorted_list_to_binary_search_tree.md: -------------------------------------------------------------------------------- 1 | ### 109. Convert Sorted List to Binary Search Tree 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 9 | 难度: 10 | 11 | Medium 12 | 13 | 思路: 14 | 15 | 跟第 108 题一样 16 | 17 | ```python 18 | class Solution(object): 19 | def sortedListToBST(self, head): 20 | """ 21 | :type head: ListNode 22 | :rtype: TreeNode 23 | """ 24 | def sortedArrayToBST(nums): 25 | if not nums: 26 | return None 27 | if nums: 28 | mid = len(nums) / 2 29 | root = TreeNode(nums[mid]) 30 | root.left = sortedArrayToBST(nums[:mid]) 31 | root.right = sortedArrayToBST(nums[mid+1:]) 32 | return root 33 | if not head: 34 | return None 35 | else: 36 | lst = [] 37 | while head: 38 | lst.append(head.val) 39 | head = head.next 40 | return sortedArrayToBST(lst) 41 | ``` 42 | -------------------------------------------------------------------------------- /Tree/read/110._balanced_binary_tree.md: -------------------------------------------------------------------------------- 1 | # 110. Balanced Binary Tree 2 | **难度: 简单** 3 | 4 | ## 刷题内容 5 | 6 | > 原题连接 7 | 8 | * https://leetcode.com/problems/balanced-binary-tree/description/ 9 | 10 | > 内容描述 11 | 12 | ``` 13 | Given a binary tree, determine if it is height-balanced. 14 | 15 | For this problem, a height-balanced binary tree is defined as: 16 | 17 | a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 18 | 19 | Example 1: 20 | 21 | Given the following tree [3,9,20,null,null,15,7]: 22 | 23 | 3 24 | / \ 25 | 9 20 26 | / \ 27 | 15 7 28 | Return true. 29 | 30 | Example 2: 31 | 32 | Given the following tree [1,2,2,3,3,null,null,4,4]: 33 | 34 | 1 35 | / \ 36 | 2 2 37 | / \ 38 | 3 3 39 | / \ 40 | 4 4 41 | Return false. 42 | ``` 43 | 44 | ## 解题方案 45 | 46 | > 思路 1 47 | 48 | 递归,判断左右子树最大高度差不超过1且左右子树均为平衡树 49 | 50 | ```python 51 | class Solution(object): 52 | def isBalanced(self, root): 53 | """ 54 | :type root: TreeNode 55 | :rtype: bool 56 | """ 57 | def height(node): 58 | if not node: 59 | return 0 60 | return 1 + max(height(node.left), height(node.right)) 61 | if not root: 62 | return True 63 | return abs(height(root.left) - height(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right) 64 | ``` 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Tree/read/112._path_sum.md: -------------------------------------------------------------------------------- 1 | ### 112. Path Sum 2 | 3 | 题目: 4 | 5 | 6 | 7 | 难度: 8 | 9 | Easy 10 | 11 | 12 | 递归 13 | 14 | ```python 15 | class Solution(object): 16 | def hasPathSum(self, root, sum): 17 | if not root: 18 | return False 19 | if root.left or root.right: 20 | return self.hasPathSum(root.left, sum-root.val) or self.hasPathSum(root.right, sum-root.val) 21 | else: 22 | return root.val == sum 23 | ``` 24 | 25 | ```python 26 | class Solution(object): 27 | def pathSum(self, root, sum): 28 | res = [] 29 | self.auxPathSum(root, sum, [], res) 30 | return res 31 | 32 | def auxPathSum(self, root, sum, cur_list, cur_lists): 33 | if not root: 34 | return 35 | if sum == root.val and not root.left and not root.right: 36 | cur_lists.append(cur_list + [root.val]) 37 | return 38 | if root.left: 39 | self.auxPathSum(root.left, sum - root.val, cur_list + [root.val], cur_lists) 40 | if root.right: 41 | self.auxPathSum(root.right, sum - root.val, cur_list + [root.val], cur_lists) 42 | ``` -------------------------------------------------------------------------------- /Tree/read/113._path_sum_ii.md: -------------------------------------------------------------------------------- 1 | ### 113. Path Sum II 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 9 | tag : DFS 10 | 11 | 12 | 难度 : Medium 13 | 14 | 15 | 注意宁愿写几次curList + [root.val] 也不要直接传一个list进去,因为list pass by reference的亏已经吃过了 16 | 17 | ```python 18 | class Solution(object): 19 | def pathSum(self, root, sum): 20 | res = [] 21 | self.auxPathSum(root, sum, [], res) 22 | return res 23 | def auxPathSum(self, root, sum, cur_list, cur_lists): 24 | if not root: 25 | return 26 | if sum == root.val and not root.left and not root.right: 27 | cur_lists.append(cur_list + [root.val]) 28 | return 29 | if root.left: 30 | self.auxPathSum(root.left, sum - root.val, cur_list + [root.val], cur_lists) 31 | if root.right: 32 | self.auxPathSum(root.right, sum - root.val, cur_list + [root.val], cur_lists) 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /Tree/read/129._sum_root_to_leaf_numbers.md: -------------------------------------------------------------------------------- 1 | #### 129. Sum Root to Leaf Numbers 2 | 3 | ```py 4 | class Solution: 5 | def sumNumbers(self, root): 6 | return self.calSum(root, 0) 7 | 8 | def calSum(self, root, curSum): 9 | if root == None: 10 | return 0 11 | else: 12 | curSum = curSum * 10 + root.val 13 | if root.left == None and root.right == None: 14 | return curSum 15 | else: 16 | return self.calSum(root.left, curSum) + self.calSum(root.right, curSum) 17 | ``` 18 | -------------------------------------------------------------------------------- /Tree/read/144._binary_tree_preorder_traversal.md: -------------------------------------------------------------------------------- 1 | 2 | > 思路 1:递归,瞬秒 3 | 4 | ```python 5 | class Solution(object): 6 | def preorderTraversal(self, root): 7 | """ 8 | :type root: TreeNode 9 | :rtype: List[int] 10 | """ 11 | if root == None: 12 | return [] 13 | res = [] 14 | self.preorder(root,res) 15 | return res 16 | 17 | def preorder(self,root,res): 18 | if root == None: 19 | return 20 | res.append(root.val) 21 | self.preorder(root.left,res) 22 | self.preorder(root.right,res) 23 | ``` 24 | 25 | > 思路 2:迭代 26 | 27 | ```python 28 | class Solution(object): 29 | def preorderTraversal(self, root): 30 | """ 31 | :type root: TreeNode 32 | :rtype: List[int] 33 | """ 34 | res = [] 35 | if not root: 36 | return res 37 | stack = [] 38 | stack.append(root) 39 | 40 | while(len(stack) > 0): 41 | node = stack.pop() 42 | res.append(node.val) 43 | if node.right: 44 | stack.append(node.right) 45 | if node.left: 46 | stack.append(node.left) 47 | return res 48 | ``` 49 | -------------------------------------------------------------------------------- /Tree/read/145._binary_tree_postorder_traversal.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | > 思路 1:递归 4 | 5 | ```python 6 | class Solution(object): 7 | def postorderTraversal(self, root): 8 | def postOrder(root): 9 | if not root : return 10 | postOrder(root.left) 11 | postOrder(root.right) 12 | res.append(root.val) 13 | res = [] 14 | postOrder(root) 15 | return res 16 | ``` 17 | 18 | > 思路 2:迭代 19 | 20 | 其实思路就一句话,后序遍历是左右中,因为我们第一个放进去的肯定是中(即root),所以我们逆向思维考虑一下,我们按照中右左的顺序放进去,然后返回res[::-1]就行了。这其实跟[leetcode第144题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/144._binary_tree_preorder_traversal.md)是一样的思路 21 | 22 | ```python 23 | class Solution(object): 24 | def postorderTraversal(self, root): 25 | res = [] 26 | if not root: 27 | return res 28 | stack1 = [] 29 | stack1.append(root) 30 | while len(stack1) > 0: 31 | node = stack1.pop() 32 | res.append(node.val) 33 | if node.left: 34 | stack1.append(node.left) 35 | if node.right: 36 | stack1.append(node.right) 37 | 38 | return res[::-1] 39 | ``` 40 | -------------------------------------------------------------------------------- /Tree/read/199._binary_tree_right_side_view.md: -------------------------------------------------------------------------------- 1 | ###199. Binary Tree Right Side View 2 | 3 | 题目: 4 | 5 | 6 | 7 | 8 | 难度: 9 | 10 | Medium 11 | 12 | 13 | 还是在玩第102题,level order traversal. 14 | 15 | ``` 16 | class Solution(object): 17 | def rightSideView(self, root): 18 | """ 19 | :type root: TreeNode 20 | :rtype: List[int] 21 | """ 22 | if root == None: return [] 23 | 24 | res = [] 25 | curLevel = [root] 26 | while curLevel: 27 | nextLevel = [] 28 | tmpRes = [] 29 | for node in curLevel: 30 | tmpRes.append(node.val) 31 | if node.left: nextLevel.append(node.left) 32 | if node.right: nextLevel.append(node.right) 33 | res.append(tmpRes[-1]) 34 | curLevel = nextLevel 35 | return res 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /Tree/read/226._invert_binary_tree.md: -------------------------------------------------------------------------------- 1 | # 226. Invert Binary Tree 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/invert-binary-tree/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Invert a binary tree. 15 | 16 | Example: 17 | 18 | Input: 19 | 20 | 4 21 | / \ 22 | 2 7 23 | / \ / \ 24 | 1 3 6 9 25 | Output: 26 | 27 | 4 28 | / \ 29 | 7 2 30 | / \ / \ 31 | 9 6 3 1 32 | Trivia: 33 | This problem was inspired by this original tweet by Max Howell: 34 | 35 | Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so f*** off. 36 | ``` 37 | 38 | ## 解题方案 39 | 40 | > 思路 1 41 | ******- 时间复杂度: O(N)******- 空间复杂度: O(1)****** 42 | 43 | 典型的递归题 44 | 45 | 46 | ```python 47 | class Solution(object): 48 | def invertTree(self, root): 49 | """ 50 | :type root: TreeNode 51 | :rtype: TreeNode 52 | """ 53 | if not root: 54 | return root 55 | root.left, root.right = root.right, root.left 56 | self.invertTree(root.left) 57 | self.invertTree(root.right) 58 | return root 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /Tree/read/450. Delete Node in a BST.md: -------------------------------------------------------------------------------- 1 | ### 450. Delete Node in a BST 2 | 3 | 4 | 5 | 题目: 6 | 7 | 8 | 难度 : Medium 9 | 10 | 11 | 12 | 思路: 13 | 14 | 从二叉搜索树中删除节点x的方法如下: 15 | 16 | • 如果x没有子节点,或者只有一个孩子,直接将x“切下”; 17 | 18 | • 否则,x有两个孩子,我们用其右子树中的最小值替换掉x,然后将右子树中的这一最小值递归的“切掉”。 19 | ​ 20 | 21 | 22 | 23 | AC代码 24 | 25 | 26 | 27 | ```python 28 | class Solution(object): 29 | def deleteNode(self, root, key): 30 | """ 31 | :type root: TreeNode 32 | :type key: int 33 | :rtype: TreeNode 34 | """ 35 | def findmin(root): 36 | while root.left: 37 | root = root.left 38 | return root 39 | 40 | 41 | if not root : return None 42 | elif key < root.val: root.left = self.deleteNode(root.left, key) 43 | elif key > root.val : root.right = self.deleteNode(root.right, key) 44 | else: 45 | if root.left and root.right: 46 | tmp = findmin(root.right) 47 | root.val = tmp.val 48 | root.right = self.deleteNode(root.right, tmp.val) 49 | else: 50 | if not root.left: 51 | root = root.right 52 | elif not root.right: 53 | root = root.left 54 | return root 55 | ``` 56 | 57 | ​ 58 | 59 | 60 | 61 | 其实这个代码还是需要花点时间来理解,需要画个图,理解这个root是每个stack return回去然后被接在原来的树上的,if 这个node并不是在node左右。 62 | 63 | -------------------------------------------------------------------------------- /Tree/read/701._Insert_into_a_Binary_Search_Tree.md: -------------------------------------------------------------------------------- 1 | # 701. Insert into a Binary Search Tree 2 | 3 | **难度: 困难** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/longest-valid-parentheses 10 | 11 | > 内容描述 12 | 13 | ``` 14 | Given the root node of a binary search tree (BST) and a value to be inserted into the tree, insert the value into the BST. Return the root node of the BST after the insertion. It is guaranteed that the new value does not exist in the original BST. 15 | 16 | Note that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return any of them. 17 | 18 | For example, 19 | 20 | Given the tree: 21 | 4 22 | / \ 23 | 2 7 24 | / \ 25 | 1 3 26 | And the value to insert: 5 27 | You can return this binary search tree: 28 | 29 | 4 30 | / \ 31 | 2 7 32 | / \ / 33 | 1 3 5 34 | This tree is also valid: 35 | 36 | 5 37 | / \ 38 | 2 7 39 | / \ 40 | 1 3 41 | \ 42 | 4 43 | ``` 44 | 45 | ## 解题方案 46 | 47 | > 思路 1 48 | 49 | 就一句话,看到树🌲就想到递归,太简单了,30秒敲完答案 50 | 51 | ```python 52 | class Solution(object): 53 | def insertIntoBST(self, root, val): 54 | """ 55 | :type root: TreeNode 56 | :type val: int 57 | :rtype: TreeNode 58 | """ 59 | if not root: 60 | return TreeNode(val) 61 | if val < root.val: 62 | root.left = self.insertIntoBST(root.left, val) 63 | if val > root.val: 64 | root.right = self.insertIntoBST(root.right, val) 65 | return root 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /Two-pointers/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kitahara-saneyuki/LCPython/81d09cdbc8150d6dc47f39994aa68cfb85b81b7f/Two-pointers/.DS_Store -------------------------------------------------------------------------------- /Two-pointers/read/125._valid_palindrome.md: -------------------------------------------------------------------------------- 1 | # 125. Valid Palindrome 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/valid-palindrome/description/ 10 | 11 | > 内容描述 12 | 13 | ```md 14 | Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 15 | 16 | Note: For the purpose of this problem, we define empty string as valid palindrome. 17 | 18 | Example 1: 19 | 20 | Input: "A man, a plan, a canal: Panama" 21 | Output: true 22 | Example 2: 23 | 24 | Input: "race a car" 25 | Output: false 26 | ``` 27 | 28 | ## 解题方案 29 | 30 | 双指针in-place 31 | 32 | 时间复杂度还是O(n), 但是空间优化到了O(1) 33 | 34 | ```python 35 | class Solution(object): 36 | def isPalindrome(self, s): 37 | """ 38 | :type s: str 39 | :rtype: bool 40 | """ 41 | l, r = 0, len(s)-1 42 | while l < r: 43 | while l < r and not s[l].isalnum(): 44 | l += 1 45 | while l < r and not s[r].isalnum(): 46 | r -= 1 47 | if s[l].lower() != s[r].lower(): 48 | return False 49 | l += 1 50 | r -= 1 51 | return True 52 | ``` 53 | -------------------------------------------------------------------------------- /Two-pointers/read/167._two_sum_ii_-_input_array_is_sorted.md: -------------------------------------------------------------------------------- 1 | # 167. Two Sum II - Input array is sorted 2 | 3 | **难度: Easy** 4 | 5 | ## 刷题内容 6 | 7 | > 原题连接 8 | 9 | * https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/ 10 | 11 | > 内容描述 12 | 13 | ``` 14 | 15 | Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. 16 | 17 | The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. 18 | 19 | Note: 20 | 21 | Your returned answers (both index1 and index2) are not zero-based. 22 | You may assume that each input would have exactly one solution and you may not use the same element twice. 23 | Example: 24 | 25 | Input: numbers = [2,7,11,15], target = 9 26 | Output: [1,2] 27 | Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2. 28 | ``` 29 | 30 | ## 解题方案 31 | 32 | > 思路 1 33 | ******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)****** 34 | 35 | 二分法+双指针,beats 86.15% 36 | 37 | ```python 38 | class Solution(object): 39 | def twoSum(self, numbers, target): 40 | """ 41 | :type numbers: List[int] 42 | :type target: int 43 | :rtype: List[int] 44 | """ 45 | l, r = 0, len(numbers) - 1 46 | while l < r: 47 | if numbers[l] + numbers[r] == target: 48 | return [l+1, r+1] 49 | elif numbers[l] + numbers[r] < target: 50 | l += 1 51 | else: 52 | r -= 1 53 | ``` 54 | --------------------------------------------------------------------------------