├── 3sum.cpp ├── 3sum_closest.cpp ├── 4sum.cpp ├── add_binary.cpp ├── add_two_numbers.cpp ├── anagrams.cpp ├── balanced_binary_tree.cpp ├── best_time_to_buy_and_sell_stock.cpp ├── best_time_to_buy_and_sell_stock_ii.cpp ├── best_time_to_buy_and_sell_stock_iii.cpp ├── binary_tree_inorder_traversal.cpp ├── binary_tree_level_order_traversal.cpp ├── binary_tree_level_order_traversal_ii.cpp ├── binary_tree_maximum_path_sum.cpp ├── binary_tree_postorder_traversal.cpp ├── binary_tree_preorder_traversal.cpp ├── binary_tree_zigzag_level_order_traversal.cpp ├── candy.cpp ├── climbing_stairs.cpp ├── clone_graph.cpp ├── combination_sum.cpp ├── combination_sum_ii.cpp ├── combinations.cpp ├── compile_check_inc.h ├── construct_binary_tree_from_inorder_and_postorder_traversal.cpp ├── construct_binary_tree_from_preorder_and_inorder_traversal.cpp ├── container_with_most_water.cpp ├── convert_sorted_array_to_binary_search_tree.cpp ├── convert_sorted_list_to_binary_search_tree.cpp ├── copy_list_with_random_pointer.cpp ├── count_and_say.cpp ├── decode_ways.cpp ├── distinct_subsequences.cpp ├── divide_two_integers.cpp ├── edit_distance.cpp ├── evaluate_reverse_polish_notation.cpp ├── first_missing_positive.cpp ├── flatten_binary_tree_to_linked_list.cpp ├── gas_station.cpp ├── generate_parentheses.cpp ├── gray_code.cpp ├── implement_strstr.cpp ├── insert_interval.cpp ├── insertion_sort_list.cpp ├── integer_to_roman.cpp ├── interleaving_string.cpp ├── jump_game.cpp ├── jump_game_ii.cpp ├── largest_rectangle_in_histogram.cpp ├── length_of_last_word.cpp ├── letter_combinations_of_a_phone_number.cpp ├── linked_list_cycle.cpp ├── linked_list_cycle_ii.cpp ├── longest_common_prefix.cpp ├── longest_consecutive_sequence.cpp ├── longest_palindromic_substring.cpp ├── longest_substring_without_repeating_characters.cpp ├── longest_valid_parentheses.cpp ├── lru_cache.cpp ├── max_points_on_a_line.cpp ├── maximal_rectangle.cpp ├── maximum_depth_of_binary_tree.cpp ├── maximum_product_subarray.cpp ├── maximum_subarray.cpp ├── median_of_two_sorted_arrays.cpp ├── merge_intervals.cpp ├── merge_k_sorted_lists.cpp ├── merge_sorted_array.cpp ├── merge_two_sorted_lists.cpp ├── minimum_depth_of_binary_tree.cpp ├── minimum_path_sum.cpp ├── minimum_window_substring.cpp ├── multiply_strings.cpp ├── n_queens.cpp ├── n_queens_ii.cpp ├── next_permutation.cpp ├── palindrome_number.cpp ├── palindrome_partitioning.cpp ├── palindrome_partitioning_ii.cpp ├── partition_list.cpp ├── pascals_triangle.cpp ├── pascals_triangle_ii.cpp ├── path_sum.cpp ├── path_sum_ii.cpp ├── permutation_sequence.cpp ├── permutations.cpp ├── permutations_ii.cpp ├── plus_one.cpp ├── populating_next_right_pointers_in_each_node.cpp ├── populating_next_right_pointers_in_each_node_ii.cpp ├── pow_x_n.cpp ├── questions.txt ├── recover_binary_search_tree.cpp ├── regular_expression_matching.cpp ├── remove_duplicates_from_sorted_array.cpp ├── remove_duplicates_from_sorted_array_ii.cpp ├── remove_duplicates_from_sorted_list.cpp ├── remove_duplicates_from_sorted_list_ii.cpp ├── remove_element.cpp ├── remove_nth_node_from_end_of_list.cpp ├── reorder_list.cpp ├── restore_ip_addresses.cpp ├── reverse_integer.cpp ├── reverse_linked_list_ii.cpp ├── reverse_nodes_in_k_group.cpp ├── reverse_words_in_a_string.cpp ├── roman_to_integer.cpp ├── rotate_image.cpp ├── rotate_list.cpp ├── same_tree.cpp ├── scramble_string.cpp ├── search_a_2d_matrix.cpp ├── search_for_a_range.cpp ├── search_in_rotated_sorted_array.cpp ├── search_in_rotated_sorted_array_ii.cpp ├── search_insert_position.cpp ├── set_matrix_zeroes.cpp ├── simplify_path.cpp ├── single_number.cpp ├── single_number_ii.cpp ├── sort_colors.cpp ├── sort_list.cpp ├── spiral_matrix.cpp ├── spiral_matrix_ii.cpp ├── sqrt_x.cpp ├── string_to_integer_atoi.cpp ├── subsets.cpp ├── subsets_ii.cpp ├── substring_with_concatenation_of_all_words.cpp ├── sudoku_solver.cpp ├── sum_root_to_leaf_numbers.cpp ├── surrounded_regions.cpp ├── swap_nodes_in_pairs.cpp ├── symmetric_tree.cpp ├── text_justification.cpp ├── trapping_rain_water.cpp ├── triangle.cpp ├── two_sum.cpp ├── unique_binary_search_trees.cpp ├── unique_binary_search_trees_ii.cpp ├── unique_paths.cpp ├── unique_paths_ii.cpp ├── valid_number.cpp ├── valid_palindrome.cpp ├── valid_parentheses.cpp ├── valid_sudoku.cpp ├── validate_binary_search_tree.cpp ├── wildcard_matching.cpp ├── word_break.cpp ├── word_break_ii.cpp ├── word_ladder.cpp ├── word_ladder_ii.cpp ├── word_search.cpp ├── zigzag_conversion.cpp └── 命名规范.txt /3sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > threeSum(vector &num) { 4 | vector > results; 5 | int i = 0; 6 | int size = num.size(); 7 | 8 | sort(num.begin(), num.end()); 9 | 10 | while (i < (size - 2)) { 11 | int pre_number = num[i]; 12 | int start = i + 1; 13 | int end = size - 1; 14 | 15 | while (start < end) { 16 | int left_val = num[start]; 17 | int right_val = num[end]; 18 | int sum = pre_number + left_val + right_val; 19 | 20 | if (sum < 0) { 21 | ++start; 22 | } 23 | else if (sum > 0) { 24 | --end; 25 | } 26 | else { 27 | vector result; 28 | 29 | result.push_back(num[i]); 30 | result.push_back(left_val); 31 | result.push_back(right_val); 32 | 33 | results.push_back(result); 34 | 35 | ++start; 36 | --end; 37 | 38 | while ((start < end) && (num[start] == left_val)) { 39 | ++start; 40 | } 41 | 42 | while ((start < end) && (num[end] == right_val)) { 43 | --end; 44 | } 45 | } 46 | } 47 | 48 | ++i; 49 | while ((i < (size - 2)) && (num[i] == pre_number)) { 50 | ++i; 51 | } 52 | } 53 | 54 | return results; 55 | } 56 | }; -------------------------------------------------------------------------------- /3sum_closest.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int threeSumClosest(vector &num, int target) { 4 | int closest; 5 | int min_diff = INT_MAX; 6 | int i = 0; 7 | int size = num.size(); 8 | 9 | sort(num.begin(), num.end()); 10 | 11 | while (i < (size - 2)) { 12 | int pre_number = num[i]; 13 | int start = i + 1; 14 | int end = size - 1; 15 | 16 | while (start < end) { 17 | int left_val = num[start]; 18 | int right_val = num[end]; 19 | int sum = pre_number + left_val + right_val; 20 | int diff = abs(sum - target); 21 | 22 | if (0 == diff) { 23 | return target; 24 | } 25 | 26 | if (diff <= min_diff) { 27 | min_diff = diff; 28 | closest = sum; 29 | } 30 | 31 | if (sum < target) { 32 | ++start; 33 | } 34 | else { 35 | --end; 36 | } 37 | } 38 | 39 | ++i; 40 | } 41 | 42 | return closest; 43 | } 44 | }; -------------------------------------------------------------------------------- /4sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > fourSum(vector &num, int target) { 4 | vector > results; 5 | int i = 0; 6 | int size = num.size(); 7 | 8 | sort(num.begin(), num.end()); 9 | 10 | while (i < (size - 3)) { 11 | int pre_first = num[i]; 12 | int j = i + 1; 13 | int tmp; 14 | 15 | while (j < (size - 2)) { 16 | int pre_second = num[j]; 17 | int two_sum = pre_first + pre_second; 18 | int start = j + 1; 19 | int end = size - 1; 20 | 21 | while (start < end) { 22 | int left_val = num[start]; 23 | int right_val = num[end]; 24 | int four_sum = two_sum + left_val + right_val; 25 | 26 | if (four_sum < target) { 27 | ++start; 28 | } 29 | else if (four_sum > target) { 30 | --end; 31 | } 32 | else { 33 | vector result; 34 | 35 | result.push_back(pre_first); 36 | result.push_back(pre_second); 37 | result.push_back(left_val); 38 | result.push_back(right_val); 39 | 40 | results.push_back(result); 41 | 42 | tmp = start + 1; 43 | 44 | while ((tmp < end) && (num[tmp] == num[start])) { 45 | ++tmp; 46 | } 47 | 48 | start = tmp; 49 | 50 | tmp = end - 1; 51 | 52 | while ((tmp > start) && (num[tmp] == num[end])) { 53 | --tmp; 54 | } 55 | 56 | end = tmp; 57 | } 58 | } 59 | 60 | tmp = j + 1; 61 | 62 | while ((tmp < (size - 2)) && (num[tmp] == num[j])) { 63 | ++tmp; 64 | } 65 | 66 | j = tmp; 67 | } 68 | 69 | tmp = i + 1; 70 | 71 | while ((tmp < (size - 3)) && (num[tmp] == num[i])) { 72 | ++tmp; 73 | } 74 | 75 | i = tmp; 76 | } 77 | 78 | return results; 79 | } 80 | }; -------------------------------------------------------------------------------- /add_binary.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string addBinary(string a, string b) { 4 | string result; 5 | int bit; 6 | int flag = 0; 7 | 8 | reverse(a.begin(), a.end()); 9 | reverse(b.begin(), b.end()); 10 | 11 | const char *a_str = a.c_str(); 12 | const char *b_str = b.c_str(); 13 | 14 | while ((*a_str != '\0') && (*b_str != '\0')) { 15 | bit = (*a_str - '0') + (*b_str - '0') + flag; 16 | result.push_back((bit % 2) + '0'); 17 | flag = bit / 2; 18 | 19 | ++a_str; 20 | ++b_str; 21 | } 22 | 23 | const char *p = ('\0' == *a_str) ? b_str : a_str; 24 | 25 | while (*p != '\0') { 26 | bit = (*p - '0') + flag; 27 | result.push_back((bit % 2) + '0'); 28 | flag = bit / 2; 29 | 30 | ++p; 31 | } 32 | 33 | if (flag > 0) { 34 | result.push_back('1'); 35 | } 36 | 37 | reverse(result.begin(), result.end()); 38 | 39 | return result; 40 | } 41 | }; -------------------------------------------------------------------------------- /add_two_numbers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void append_to_tail(ListNode *node, ListNode *&head, ListNode *&tail) { 4 | if (NULL == head) { 5 | head = node; 6 | tail = node; 7 | } 8 | else { 9 | tail->next = node; 10 | tail = node; 11 | } 12 | } 13 | 14 | ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { 15 | ListNode *head = NULL; 16 | ListNode *tail = NULL; 17 | int sum; 18 | int flag = 0; // 标志进位 19 | 20 | while ((l1 != NULL) || (l2 != NULL)) { 21 | sum = ((l1 != NULL) ? l1->val : 0) + ((l2 != NULL) ? l2->val : 0) + flag; 22 | flag = sum / 10; 23 | 24 | append_to_tail(new ListNode(sum % 10), head, tail); 25 | 26 | l1 = (l1 != NULL) ? l1->next : NULL; 27 | l2 = (l2 != NULL) ? l2->next : NULL; 28 | } 29 | 30 | if (flag > 0) { 31 | append_to_tail(new ListNode(flag), head, tail); 32 | } 33 | 34 | return head; 35 | } 36 | }; -------------------------------------------------------------------------------- /anagrams.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // Anagrams就是季哥单词,如果每种字母出现的个数都相同, 4 | // 不考虑顺序,那么它们就是一类的。 5 | vector anagrams(vector &strs) { 6 | vector results; 7 | map dict; 8 | int size = strs.size(); 9 | 10 | for (int i = 0; i < size; ++i) { 11 | string str = strs[i]; 12 | 13 | sort(str.begin(), str.end()); 14 | 15 | if (dict.find(str) != dict.end()) { 16 | int index = dict[str]; 17 | 18 | if (index >= 0) { 19 | results.push_back(strs[index]); 20 | dict[str] = -1; // 已经输出,下次不需要再输出了。 21 | } 22 | 23 | results.push_back(strs[i]); 24 | } 25 | else { 26 | dict[str] = i; 27 | } 28 | } 29 | 30 | return results; 31 | } 32 | }; -------------------------------------------------------------------------------- /balanced_binary_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_balanced(TreeNode *root, int &height) { 4 | if (NULL == root) { 5 | height = 0; 6 | 7 | return true; 8 | } 9 | 10 | int left_height; 11 | int right_height; 12 | bool is_left_balanced = is_balanced(root->left, left_height); 13 | bool is_right_balanced = is_balanced(root->right, right_height); 14 | 15 | height = 1 + max(left_height, right_height); 16 | 17 | if (is_left_balanced && is_right_balanced) { 18 | return (abs(left_height - right_height) <= 1) ? true : false; 19 | } 20 | else { 21 | return false; 22 | } 23 | } 24 | 25 | bool isBalanced(TreeNode *root) { 26 | int height; 27 | 28 | return is_balanced(root, height); 29 | } 30 | }; -------------------------------------------------------------------------------- /best_time_to_buy_and_sell_stock.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | if (prices.size() <= 1) { 5 | return 0; 6 | } 7 | 8 | int max_profit = 0; 9 | int min_price = prices[0]; 10 | 11 | for (int i = 1; i < prices.size(); ++i) { 12 | int profit = prices[i] - min_price; 13 | 14 | if (profit < 0) { 15 | min_price = prices[i]; 16 | } 17 | else if (profit > 0) { 18 | if (profit > max_profit) { 19 | max_profit = profit; 20 | } 21 | } 22 | } 23 | 24 | return max_profit; 25 | } 26 | }; -------------------------------------------------------------------------------- /best_time_to_buy_and_sell_stock_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | int profit = 0; 5 | int size = prices.size(); 6 | int buy_price = -1; 7 | int i; 8 | 9 | for (i = 0; i < (size - 1); ++i) { 10 | if (-1 == buy_price) { 11 | if (prices[i] < prices[i + 1]) { 12 | buy_price = prices[i]; 13 | } 14 | else { 15 | continue; 16 | } 17 | } 18 | else { 19 | if (prices[i] > prices[i + 1]) { 20 | profit += prices[i] - buy_price; 21 | buy_price = -1; 22 | } 23 | } 24 | } 25 | 26 | if (buy_price != -1) { 27 | profit += prices[i] - buy_price; 28 | } 29 | 30 | return profit; 31 | } 32 | }; -------------------------------------------------------------------------------- /best_time_to_buy_and_sell_stock_iii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | if (prices.size() <= 1) { 5 | return 0; 6 | } 7 | 8 | int max_profit = 0; 9 | int max_profit_1 = 0; 10 | int max_profit_2 = 0; 11 | int size = prices.size(); 12 | int min_price = prices[0]; 13 | int max_price = prices[size - 1]; 14 | vector profits(size, 0); 15 | int i; 16 | 17 | for (i = 1; i < size; ++i) { 18 | int profit = prices[i] - min_price; 19 | 20 | if (profit < 0) { 21 | min_price = prices[i]; 22 | } 23 | else { 24 | if (profit > max_profit_1) { 25 | max_profit_1 = profit; 26 | } 27 | } 28 | 29 | profits[i] = max_profit_1; 30 | } 31 | 32 | // 从后向前,搜索第2次交易的机会。这样可以利用第一次的成果! 33 | for (i = size - 2; i >= 0; --i) { 34 | int profit = max_price - prices[i]; 35 | 36 | if (profit < 0) { 37 | max_price = prices[i]; 38 | } 39 | else { 40 | if (profit > max_profit_2) { 41 | max_profit_2 = profit; 42 | } 43 | 44 | if ((max_profit_2 + profits[i]) > max_profit) { 45 | max_profit = max_profit_2 + profits[i]; 46 | } 47 | } 48 | } 49 | 50 | return max_profit; 51 | } 52 | }; -------------------------------------------------------------------------------- /binary_tree_inorder_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void inorder_traversal(TreeNode *root, vector &result) { 4 | if (NULL == root) { 5 | return; 6 | } 7 | 8 | inorder_traversal(root->left, result); 9 | result.push_back(root->val); 10 | inorder_traversal(root->right, result); 11 | } 12 | 13 | vector inorderTraversal(TreeNode *root) { 14 | vector result; 15 | 16 | inorder_traversal(root, result); 17 | 18 | return result; 19 | } 20 | }; -------------------------------------------------------------------------------- /binary_tree_level_order_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > levelOrder(TreeNode *root) { 4 | vector > result; 5 | queue queues[2]; 6 | int curr_queue = 0; 7 | int next_queue = 1; 8 | 9 | if (NULL == root) { 10 | return result; 11 | } 12 | 13 | queues[curr_queue].push(root); 14 | 15 | while (!queues[curr_queue].empty()) { 16 | vector level; 17 | 18 | while (!queues[curr_queue].empty()) { 19 | TreeNode *node = queues[curr_queue].front(); 20 | 21 | queues[curr_queue].pop(); 22 | 23 | if (node->left != NULL) { 24 | queues[next_queue].push(node->left); 25 | } 26 | 27 | if (node->right != NULL) { 28 | queues[next_queue].push(node->right); 29 | } 30 | 31 | level.push_back(node->val); 32 | } 33 | 34 | result.push_back(level); 35 | swap(curr_queue, next_queue); 36 | } 37 | 38 | return result; 39 | } 40 | }; -------------------------------------------------------------------------------- /binary_tree_level_order_traversal_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > levelOrderBottom(TreeNode *root) { 4 | vector > result; 5 | queue queues[2]; 6 | int curr_queue = 0; 7 | int next_queue = 1; 8 | 9 | if (NULL == root) { 10 | return result; 11 | } 12 | 13 | queues[curr_queue].push(root); 14 | 15 | while (!queues[curr_queue].empty()) { 16 | vector level; 17 | 18 | while (!queues[curr_queue].empty()) { 19 | TreeNode *node = queues[curr_queue].front(); 20 | 21 | queues[curr_queue].pop(); 22 | 23 | if (node->left != NULL) { 24 | queues[next_queue].push(node->left); 25 | } 26 | 27 | if (node->right != NULL) { 28 | queues[next_queue].push(node->right); 29 | } 30 | 31 | level.push_back(node->val); 32 | } 33 | 34 | result.push_back(level); 35 | swap(curr_queue, next_queue); 36 | } 37 | 38 | reverse(result.begin(), result.end()); 39 | 40 | return result; 41 | } 42 | }; -------------------------------------------------------------------------------- /binary_tree_maximum_path_sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int max_path_sum(TreeNode *root, int &max_sum) { 4 | if ((NULL == root->left) && (NULL == root->right)) { 5 | if (root->val > max_sum) { 6 | max_sum = root->val; 7 | } 8 | 9 | return root->val; 10 | } 11 | else { 12 | int tmp = root->val; 13 | int left_max = INT_MIN; 14 | int right_max = INT_MIN; 15 | 16 | if (root->left != NULL) { 17 | left_max = max_path_sum(root->left, max_sum); 18 | } 19 | 20 | if (root->right != NULL) { 21 | right_max = max_path_sum(root->right, max_sum); 22 | } 23 | 24 | if (left_max > 0) { 25 | tmp += left_max; 26 | left_max += root->val; 27 | } 28 | 29 | if (right_max > 0) { 30 | tmp += right_max; 31 | right_max += root->val; 32 | } 33 | 34 | if (tmp > max_sum) { 35 | max_sum = tmp; 36 | } 37 | 38 | return max(root->val, max(left_max, right_max)); 39 | } 40 | } 41 | int maxPathSum(TreeNode *root) { 42 | int max_sum = INT_MIN; 43 | 44 | max_path_sum(root, max_sum); 45 | 46 | return max_sum; 47 | } 48 | }; -------------------------------------------------------------------------------- /binary_tree_postorder_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector postorderTraversal(TreeNode *root) { 4 | vector result; 5 | stack s; 6 | map right_visited; 7 | 8 | s.push(NULL); 9 | 10 | while ((root != NULL) || (s.top() != NULL)) { 11 | while (root != NULL) { 12 | s.push(root); 13 | root = root->left; 14 | } 15 | 16 | root = s.top(); 17 | 18 | if (NULL == root) { 19 | break; 20 | } 21 | else { 22 | while ((right_visited[root]) && (root != NULL)) { 23 | result.push_back(root->val); 24 | s.pop(); 25 | root = s.top(); 26 | } 27 | 28 | right_visited[root] = true; 29 | 30 | if (root != NULL) { 31 | root = root->right; 32 | } 33 | } 34 | } 35 | 36 | return result; 37 | } 38 | }; -------------------------------------------------------------------------------- /binary_tree_preorder_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector preorderTraversal(TreeNode *root) { 4 | vector result; 5 | stack s; 6 | 7 | if (NULL == root) { 8 | return result; 9 | } 10 | 11 | s.push(NULL); 12 | 13 | while (root != NULL) { 14 | while ((root != NULL) || (s.top() != NULL)) { 15 | while (root != NULL) { 16 | result.push_back(root->val); 17 | s.push(root); 18 | root = root->left; 19 | } 20 | 21 | root = s.top(); 22 | s.pop(); 23 | root = root->right; 24 | } 25 | } 26 | 27 | return result; 28 | } 29 | }; -------------------------------------------------------------------------------- /binary_tree_zigzag_level_order_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > zigzagLevelOrder(TreeNode *root) { 4 | vector > result; 5 | vector levels[2]; 6 | int curr = 0; 7 | int next = 1; 8 | bool flag = false; 9 | 10 | if (root != NULL) { 11 | levels[curr].push_back(root); 12 | } 13 | 14 | while (!levels[curr].empty()) { 15 | vector level; 16 | int curr_size = levels[curr].size(); 17 | 18 | for (int i = 0; i < curr_size; ++i) { 19 | level.push_back(levels[curr][i]->val); 20 | 21 | if (levels[curr][i]->left != NULL) { 22 | levels[next].push_back(levels[curr][i]->left); 23 | } 24 | 25 | if (levels[curr][i]->right != NULL) { 26 | levels[next].push_back(levels[curr][i]->right); 27 | } 28 | } 29 | 30 | if (flag) { 31 | reverse(level.begin(), level.end()); 32 | } 33 | 34 | result.push_back(level); 35 | swap(curr, next); 36 | levels[next].clear(); 37 | flag = !flag; 38 | } 39 | 40 | return result; 41 | } 42 | }; -------------------------------------------------------------------------------- /candy.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int candy(vector &ratings) { 4 | int sum = 0; 5 | int number = ratings.size(); 6 | vector candies(number, 1); // 每人至少1粒糖 7 | 8 | for (int i = 1; i < number; ++i) { 9 | if (ratings[i] > ratings[i - 1]) { 10 | candies[i] = candies[i - 1] + 1; 11 | } 12 | } 13 | 14 | for (int i = number - 2; i >= 0; --i) { 15 | if (ratings[i] > ratings[i + 1]) { 16 | if (candies[i] <= candies[i + 1]) { 17 | candies[i] = candies[i + 1] + 1; 18 | } 19 | } 20 | } 21 | 22 | for (int i = 0; i < number; ++i) { 23 | sum += candies[i]; 24 | } 25 | 26 | return sum; 27 | } 28 | }; -------------------------------------------------------------------------------- /climbing_stairs.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int climbStairs(int n) { 4 | if ((0 == n) || (1 == n)) { 5 | return 1; 6 | } 7 | else if (2 == n) { 8 | return 2; 9 | } 10 | else { 11 | int steps; 12 | int n0 = 1; 13 | int n1 = 2; 14 | 15 | for (int i = 2; i < n; ++i) { 16 | steps = n0 + n1; 17 | n0 = n1; 18 | n1 = steps; 19 | } 20 | 21 | return steps; 22 | } 23 | } 24 | }; -------------------------------------------------------------------------------- /clone_graph.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { 4 | map cloned; 5 | 6 | return _clone_graph(node, cloned); 7 | } 8 | 9 | protected: 10 | UndirectedGraphNode* _clone_graph(UndirectedGraphNode *node, 11 | map &cloned) { 12 | if (NULL == node) { 13 | return NULL; 14 | } 15 | else if (cloned.find(node) != cloned.end()) { 16 | return cloned[node]; 17 | } 18 | 19 | UndirectedGraphNode *cnode = new UndirectedGraphNode(node->label); 20 | 21 | cloned[node] = cnode; 22 | 23 | for (int i = 0; i < (node->neighbors).size(); ++i) { 24 | (cnode->neighbors).push_back(_clone_graph((node->neighbors)[i], cloned)); 25 | } 26 | 27 | return cnode; 28 | } 29 | }; -------------------------------------------------------------------------------- /combination_sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 原理分析 4 | // 显然是个递归问题。 5 | // 以[2, 3, 6, 7],目标为7举例: 6 | // [2],[2, 3, 6, 7] => 5 7 | // [2, 2], [3, 6, 7] => 3 8 | // [2]. [3, 6, 7] => 5 9 | // ... 10 | void combination_sum(vector &candidates, 11 | int target, 12 | int start, 13 | int sum, 14 | vector &combination, 15 | vector > &results) { 16 | int size = candidates.size(); 17 | 18 | if (sum == target) { 19 | results.push_back(combination); 20 | } 21 | else if ((start < size) && (sum < target)) { 22 | for (int i = start; i < size; ) { 23 | int val = candidates[i]; 24 | 25 | combination.push_back(val); 26 | combination_sum(candidates, target, i, sum + val, combination, results); 27 | combination.pop_back(); 28 | 29 | // 重复的数字跳过 30 | int j = i + 1; 31 | 32 | while (j < size) { 33 | if (candidates[i] == candidates[j]) { 34 | ++j; 35 | } 36 | else { 37 | break; 38 | } 39 | } 40 | 41 | i = j; 42 | } 43 | } 44 | } 45 | 46 | vector > combinationSum(vector &candidates, int target) { 47 | vector > results; 48 | vector combination; 49 | 50 | // 排序使得我们可以正确的处理重复的数字 51 | sort(candidates.begin(), candidates.end()); 52 | 53 | combination_sum(candidates, target, 0, 0, combination, results); 54 | 55 | return results; 56 | } 57 | }; -------------------------------------------------------------------------------- /combination_sum_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 参考Combination Sum,这里更简单,同一个数不需要重复使用。 4 | void combination_sum_2(vector &num, 5 | int target, 6 | int start, 7 | int sum, 8 | vector &combination, 9 | vector > &results) { 10 | int size = num.size(); 11 | 12 | if (sum == target) { 13 | results.push_back(combination); 14 | } 15 | else if ((start < size) && (sum < target)) { 16 | for (int i = start; i < size; ) { 17 | int val = num[i]; 18 | 19 | combination.push_back(val); 20 | // 变化在这步 21 | combination_sum_2(num, target, i + 1, sum + val, combination, results); 22 | combination.pop_back(); 23 | 24 | // 这里还是需要考虑去重,考虑num = [1, 1, 2],target = 2的情况。 25 | int j = i + 1; 26 | 27 | while (j < size) { 28 | if (val == num[j]) { 29 | ++j; 30 | } 31 | else { 32 | break; 33 | } 34 | } 35 | 36 | i = j; 37 | } 38 | } 39 | } 40 | 41 | vector > combinationSum2(vector &num, int target) { 42 | vector > results; 43 | vector combination; 44 | 45 | // 这里排序是为了保证输出顺序 46 | sort(num.begin(), num.end()); 47 | 48 | combination_sum_2(num, target, 0, 0, combination, results); 49 | 50 | return results; 51 | } 52 | }; -------------------------------------------------------------------------------- /combinations.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void generate_combinations(vector &numbers, 4 | int index, 5 | int count, 6 | vector &combination, 7 | vector > &combinations) { 8 | if (0 == count) { 9 | combinations.push_back(combination); 10 | } 11 | else { 12 | for (int i = index; i <= (numbers.size() - count); ++i) { 13 | combination.push_back(numbers[i]); 14 | generate_combinations(numbers, i + 1, count - 1, combination, combinations); 15 | combination.pop_back(); 16 | } 17 | } 18 | } 19 | 20 | vector > combine(int n, int k) { 21 | vector > combinations; 22 | vector combination; 23 | vector numbers; 24 | 25 | for (int i = 1; i <= n; ++i) { 26 | numbers.push_back(i); 27 | } 28 | 29 | generate_combinations(numbers, 0, k, combination, combinations); 30 | 31 | return combinations; 32 | } 33 | }; -------------------------------------------------------------------------------- /compile_check_inc.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | struct ListNode { 16 | int val; 17 | ListNode *next; 18 | ListNode(int x, ListNode *_next = NULL) : val(x), next(_next) {} 19 | }; 20 | 21 | struct TreeNode { 22 | int val; 23 | TreeNode *left; 24 | TreeNode *right; 25 | TreeNode(int x, TreeNode *_left = NULL, TreeNode *_right = NULL) : 26 | val(x), left(_left), right(_right) {} 27 | }; 28 | 29 | struct UndirectedGraphNode { 30 | int label; 31 | vector neighbors; 32 | UndirectedGraphNode(int x) : label(x) {} 33 | }; 34 | 35 | struct RandomListNode { 36 | int label; 37 | RandomListNode *next; 38 | RandomListNode *random; 39 | RandomListNode(int x) : label(x), next(NULL), random(NULL) {} 40 | }; -------------------------------------------------------------------------------- /construct_binary_tree_from_inorder_and_postorder_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 参考construct_binary_tree_from_preorder_and_inorder_traversal.cpp 4 | TreeNode* build_tree(vector &inorder, 5 | int in_start, 6 | int in_end, 7 | vector &postorder, 8 | int post_start, 9 | int post_end) { 10 | if (post_start > post_end) { 11 | return NULL; 12 | } 13 | else if (post_start == post_end) { 14 | return new TreeNode(postorder[post_start]); 15 | } 16 | 17 | int i = 0; 18 | 19 | for ( ; (in_start + i) <= in_end; ++i) { 20 | if (inorder[in_start + i] == postorder[post_end]) { 21 | break; 22 | } 23 | } 24 | 25 | TreeNode *root = new TreeNode(postorder[post_end]); 26 | 27 | root->left = build_tree(inorder, 28 | in_start, 29 | in_end + (i - 1), 30 | postorder, 31 | post_start, 32 | post_start + (i - 1)); 33 | root->right = build_tree(inorder, 34 | in_start + (i + 1), 35 | in_end, 36 | postorder, 37 | post_start + i, 38 | post_end - 1); 39 | 40 | return root; 41 | } 42 | 43 | TreeNode *buildTree(vector &inorder, vector &postorder) { 44 | return build_tree(inorder, 45 | 0, 46 | inorder.size() - 1, 47 | postorder, 48 | 0, 49 | postorder.size() - 1); 50 | } 51 | }; -------------------------------------------------------------------------------- /construct_binary_tree_from_preorder_and_inorder_traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode* build_tree(vector &preorder, 4 | int pre_start, 5 | int pre_end, 6 | vector &inorder, 7 | int in_start, 8 | int in_end) { 9 | if (pre_start > pre_end) { 10 | return NULL; 11 | } 12 | else if (pre_start == pre_end) { 13 | return new TreeNode(preorder[pre_start]); 14 | } 15 | 16 | int i = 0; 17 | 18 | // 找到中间节点 19 | for ( ; (in_start + i) <= in_end; ++i) { 20 | if (preorder[pre_start] == inorder[in_start + i]) { 21 | break; 22 | } 23 | } 24 | 25 | // 确定根节点 26 | TreeNode *root = new TreeNode(preorder[pre_start]); 27 | 28 | root->left = build_tree(preorder, 29 | pre_start + 1, 30 | pre_start + i, 31 | inorder, 32 | in_start, 33 | in_start + (i - 1)); 34 | root->right = build_tree(preorder, 35 | pre_start + (i + 1), 36 | pre_end, 37 | inorder, 38 | in_start + (i + 1), 39 | in_end); 40 | 41 | return root; 42 | } 43 | 44 | TreeNode *buildTree(vector &preorder, vector &inorder) { 45 | return build_tree(preorder, 46 | 0, 47 | preorder.size() - 1, 48 | inorder, 49 | 0, 50 | inorder.size() - 1); 51 | } 52 | }; -------------------------------------------------------------------------------- /container_with_most_water.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxArea(vector &height) { 4 | int width = height.size(); 5 | int left = 0; 6 | int right = width - 1; 7 | int next; 8 | int max = 0; 9 | 10 | while (left < right) { 11 | int area = std::min(height[left], height[right]) * (right - left); 12 | 13 | if (area > max) { 14 | max = area; 15 | } 16 | 17 | if (height[left] > height[right]) { 18 | next = right - 1; 19 | 20 | while ((next > left) && (height[next] <= height[right])) { 21 | --next; 22 | } 23 | 24 | right = next; 25 | } 26 | else { 27 | next = left + 1; 28 | 29 | while ((next < right) && (height[next] <= height[left])) { 30 | ++next; 31 | } 32 | 33 | left = next; 34 | } 35 | } 36 | 37 | return max; 38 | } 39 | }; -------------------------------------------------------------------------------- /convert_sorted_array_to_binary_search_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode* convert_sorted_array_to_bst(vector &num, 4 | int min, 5 | int max) { 6 | if (min > max) { 7 | return NULL; 8 | } 9 | else { 10 | int mid = (min + max) / 2; 11 | TreeNode *root = new TreeNode(num[mid]); 12 | 13 | root->left = convert_sorted_array_to_bst(num, min, mid - 1); 14 | root->right = convert_sorted_array_to_bst(num, mid + 1, max); 15 | 16 | return root; 17 | } 18 | } 19 | 20 | TreeNode *sortedArrayToBST(vector &num) { 21 | return convert_sorted_array_to_bst(num, 0, num.size() - 1); 22 | } 23 | }; -------------------------------------------------------------------------------- /convert_sorted_list_to_binary_search_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode *sortedListToBST(ListNode *head) { 4 | if (NULL == head) { 5 | return NULL; 6 | } 7 | 8 | ListNode *curr = head; 9 | ListNode *next = head; 10 | ListNode *prev = NULL; 11 | 12 | while (next != NULL) { 13 | // 通过走一步/两步找到中间节点 14 | next = next->next; 15 | 16 | if (NULL == next) { 17 | break; 18 | } 19 | 20 | next = next->next; 21 | prev = curr; 22 | curr = curr->next; 23 | } 24 | 25 | if (NULL == curr) { 26 | return new TreeNode(head->val); 27 | } 28 | else { 29 | TreeNode *root = new TreeNode(curr->val); 30 | 31 | // 把链表拆成两端递归 32 | if (prev != NULL) { 33 | prev->next = NULL; 34 | root->left = sortedListToBST(head); 35 | } 36 | 37 | root->right = sortedListToBST(curr->next); 38 | 39 | return root; 40 | } 41 | } 42 | }; -------------------------------------------------------------------------------- /copy_list_with_random_pointer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | RandomListNode *copyRandomList(RandomListNode *head) { 4 | map copied; 5 | 6 | return copy_random_list(head, copied); 7 | } 8 | 9 | protected: 10 | RandomListNode* copy_random_list(RandomListNode *head, 11 | map &copied) { 12 | if (NULL == head) { 13 | return NULL; 14 | } 15 | else if (copied.find(head) != copied.end()) { 16 | return copied[head]; 17 | } 18 | 19 | RandomListNode *node = new RandomListNode(head->label); 20 | 21 | copied[head] = node; 22 | node->next = copy_random_list(head->next, copied); 23 | node->random = copy_random_list(head->random, copied); 24 | 25 | return node; 26 | } 27 | }; -------------------------------------------------------------------------------- /count_and_say.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string countAndSay(int n) { 4 | string results[2]; 5 | int current = 0; // 两个buffer来回切换 6 | int next = 1; 7 | 8 | results[current] = "1"; // 初始条件 9 | 10 | for (int i = 1; i < n; ++i) { 11 | int len = results[current].length(); 12 | 13 | for (int j = 0; j < len; ) { 14 | int c = results[current][j]; 15 | int k = j + 1; 16 | int sum = 1; 17 | 18 | // 开始计数 19 | while (k < len) { 20 | if (results[current][k] == c) { 21 | ++k; 22 | ++sum; 23 | } 24 | else { 25 | break; 26 | } 27 | } 28 | 29 | // 放心,不会出现sum两位数的情况。 30 | results[next].append(1, '0' + sum); 31 | results[next].append(1, c); 32 | 33 | j = k; 34 | } 35 | 36 | swap(current, next); 37 | results[next].clear(); 38 | } 39 | 40 | return results[current]; 41 | } 42 | }; -------------------------------------------------------------------------------- /decode_ways.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int calc_decode_ways(string &s, 4 | int index, 5 | vector &cached_ways) { 6 | int len = s.length(); 7 | 8 | if (index >= len) { 9 | return 1; 10 | } 11 | else if (cached_ways[index] >= 0) { 12 | return cached_ways[index]; 13 | } 14 | else { 15 | int v1 = s[index] - '0'; 16 | int v2 = -1; 17 | 18 | if (0 == v1) { 19 | cached_ways[index] = 0; 20 | return 0; 21 | } 22 | else { 23 | int ways = calc_decode_ways(s, index + 1, cached_ways); 24 | 25 | if ((index + 1) < len) { 26 | v2 = v1 * 10 + (s[index + 1] - '0'); 27 | 28 | if ((v1 >= 1) && (v2 <= 26)) { 29 | ways += calc_decode_ways(s, index + 2, cached_ways); 30 | } 31 | } 32 | 33 | cached_ways[index] = ways; 34 | 35 | return ways; 36 | } 37 | } 38 | } 39 | 40 | int numDecodings(string s) { 41 | int len = s.length(); 42 | 43 | if (0 == len) { 44 | return 0; 45 | } 46 | 47 | vector cached_ways(len, -1); 48 | 49 | calc_decode_ways(s, 0, cached_ways); 50 | 51 | return cached_ways[0]; 52 | } 53 | }; -------------------------------------------------------------------------------- /distinct_subsequences.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int count_matches(const string &s, 4 | int s_index, 5 | const string &t, 6 | int t_index, 7 | vector > &matches) { 8 | if ('\0' == t[t_index]) { 9 | return 1; 10 | } 11 | else if ('\0' == s[s_index]) { 12 | return 0; 13 | } 14 | else { 15 | if (matches[s_index][t_index] != -1) { 16 | return matches[s_index][t_index]; 17 | } 18 | 19 | int count = 0; 20 | 21 | for (int i = s_index; i < s.length(); ++i) { 22 | if (s[i] == t[t_index]) { 23 | count += count_matches(s, i + 1, t, t_index + 1, matches); 24 | } 25 | } 26 | 27 | matches[s_index][t_index] = count; 28 | 29 | return count; 30 | } 31 | } 32 | 33 | int numDistinct(string S, string T) { 34 | int s_len = S.length(); 35 | int t_len = T.length(); 36 | 37 | if ((0 == s_len) || (0 == t_len)) { 38 | return 0; 39 | } 40 | 41 | vector > matches(s_len, vector(t_len, -1)); 42 | 43 | return count_matches(S, 0, T, 0, matches); 44 | } 45 | }; -------------------------------------------------------------------------------- /divide_two_integers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | long long internal_divide(unsigned long long dividend, unsigned long long divisor) { 4 | if (dividend < divisor) { 5 | return 0; 6 | } 7 | 8 | long long result = 1; 9 | unsigned long long tmp = divisor; 10 | unsigned long long rest; 11 | 12 | while (tmp <= dividend) { 13 | rest = dividend - tmp; 14 | tmp <<= 1; 15 | 16 | if (tmp > dividend) { 17 | break; 18 | } 19 | else { 20 | result <<= 1; 21 | } 22 | } 23 | 24 | return result + internal_divide(rest, divisor); 25 | } 26 | 27 | int divide(int dividend, int divisor) { 28 | unsigned long long _dividend = abs((long long)dividend); 29 | unsigned long long _divisor = abs((long long)divisor); 30 | long long result = internal_divide(_dividend, _divisor); 31 | bool positive = (((dividend >= 0) && (divisor > 0)) || ((dividend < 0) && (divisor < 0))); 32 | 33 | return positive ? result : (-1) * result; 34 | } 35 | }; -------------------------------------------------------------------------------- /edit_distance.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int min_distance(string word_1, 4 | int index_1, 5 | string word_2, 6 | int index_2, 7 | vector > &cached_distances) { 8 | int len_1 = word_1.length(); 9 | int len_2 = word_2.length(); 10 | 11 | if (index_1 >= len_1) { 12 | // 字符串1已经到了尾部,距离就是字符串2剩下的长度。 13 | return (len_2 - index_2); 14 | } 15 | else if (index_2 >= len_2) { 16 | return (len_1 - index_1); 17 | } 18 | 19 | if (cached_distances[index_1][index_2] > 0) { 20 | return cached_distances[index_1][index_2]; 21 | } 22 | else { 23 | // word_1或者word_2插入一个字符,取较小值。 24 | int dist_1 = 1 + min(min_distance(word_1, index_1, word_2, index_2 + 1, cached_distances), 25 | min_distance(word_1, index_1 + 1, word_2, index_2, cached_distances)); 26 | 27 | // 如果word_1[index_1]不等于word_2[index_2],则做一次修改,继续比较取较小值。 28 | int dist_2 = min_distance(word_1, index_1 + 1, word_2, index_2 + 1, cached_distances); 29 | if (word_1[index_1] != word_2[index_2]) { 30 | dist_2 += 1; 31 | } 32 | 33 | cached_distances[index_1][index_2] = min(dist_1, dist_2); 34 | } 35 | } 36 | 37 | int minDistance(string word1, string word2) { 38 | // 保存计算结果,空间换时间。 39 | vector > cached_distances(word1.length(), vector(word2.length(), -1)); 40 | 41 | return min_distance(word1, 0, word2, 0, cached_distances); 42 | } 43 | }; -------------------------------------------------------------------------------- /evaluate_reverse_polish_notation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int evalRPN(vector &tokens) { 4 | stack results; 5 | 6 | for (int i = 0; i < tokens.size(); ++i) { 7 | string token = tokens[i]; 8 | 9 | if (is_operator(token)) { 10 | int val_1; 11 | int val_2; 12 | 13 | val_2 = results.top(); 14 | results.pop(); 15 | val_1 = results.top(); 16 | results.pop(); 17 | 18 | results.push(do_op(val_1, val_2, token)); 19 | } 20 | else { 21 | results.push(atoi(token.c_str())); 22 | } 23 | } 24 | 25 | return results.top(); 26 | } 27 | 28 | protected: 29 | bool is_operator(string &token) { 30 | char op = token[0]; 31 | 32 | return (1 == token.length()) && 33 | (('+' == op) || 34 | ('-' == op) || 35 | ('*' == op) || 36 | ('/' == op)); 37 | } 38 | 39 | int do_op(int val_1, int val_2, string &token) { 40 | char op = token[0]; 41 | 42 | switch(op) { 43 | case '+': 44 | return val_1 + val_2; 45 | case '-': 46 | return val_1 - val_2; 47 | case '*': 48 | return val_1 * val_2; 49 | default: // '/' 50 | return val_1 / val_2; 51 | } 52 | } 53 | }; -------------------------------------------------------------------------------- /first_missing_positive.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 原理分析 4 | // 难点在于O(n)的时间复杂度和O(1)的空间复杂度。 5 | // 办法也很简单,就是不断交换位置: 6 | // 1. 数组大小为size 7 | // 2. 如果A[i] < 0或者A[i] > size或者A[i] = i - 1,不处理。 8 | // 3. 对于A[i],如果A[i] > 0并且A[i] <= size,把A[i]和A[A[i] - 1]交换,再检查交换后的A[i]是否要继续做交换。 9 | // 4. 顺序遍历数组,找到第一个不满足A[i] = i + 1的数。 10 | int firstMissingPositive(int A[], int n) { 11 | if (0 == n) { 12 | return 1; 13 | } 14 | 15 | int i; 16 | 17 | for (i = 0; i < n; ++i) { 18 | int val = A[i]; 19 | 20 | if (val != (i + 1)) { 21 | while ((val > 0) && (val <= n) && (A[val - 1] != val)) { 22 | int tmp = A[val - 1]; 23 | 24 | A[val - 1] = val; 25 | val = tmp; 26 | } 27 | } 28 | } 29 | 30 | for (i = 0; i < n; ++i) { 31 | if (A[i] != (i + 1)) { 32 | return i + 1; 33 | } 34 | } 35 | 36 | return n + 1; 37 | } 38 | }; -------------------------------------------------------------------------------- /flatten_binary_tree_to_linked_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void flatten(TreeNode *root) { 4 | if (NULL != root) { 5 | TreeNode *left = root->left; 6 | TreeNode *right = root->right; 7 | 8 | if (left != NULL) { 9 | flatten(root->left); 10 | } 11 | 12 | if (right != NULL) { 13 | flatten(root->right); 14 | } 15 | 16 | root->left = NULL; 17 | if (left != NULL) { 18 | root->right = left; 19 | 20 | while (left != NULL) { 21 | if (NULL == left->right) { 22 | break; 23 | } 24 | 25 | left = left->right; 26 | } 27 | 28 | left->right = right; 29 | } 30 | } 31 | } 32 | }; -------------------------------------------------------------------------------- /gas_station.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 这里有一个重要的假设,如果从某个a点出发到b点失败, 4 | // 那么a到b任何一点都不能成功。证明如下: 5 | // 1. 如果能从a点加油后先开到a1点,剩余的汽油必定大于等于0。 6 | // 2. 如果放弃a点,那么从a1的出发的油量不会更多。 7 | // 3. 同理可以一直推理下去。 8 | int canCompleteCircuit(vector &gas, vector &cost) { 9 | int number = gas.size(); 10 | 11 | for (int i = 0; i < number; ++i) { 12 | int j = i; 13 | int count = 1; 14 | int gas_count = 0; 15 | 16 | while (count <= number) { 17 | if ((gas_count + gas[j % number]) >= cost[j % number]) { 18 | if (count == number) { 19 | return i; 20 | } 21 | 22 | gas_count += (gas[j % number] - cost[j % number]); 23 | ++j; 24 | ++count; 25 | } 26 | else { 27 | i = j; // 从j后面一个站点开始 28 | break; 29 | } 30 | } 31 | } 32 | 33 | return -1; 34 | } 35 | }; -------------------------------------------------------------------------------- /generate_parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void generate_parenthesis(int n, 4 | int number_of_left_pars, 5 | int number_of_right_pars, 6 | string &str, 7 | vector &results) { 8 | if ((n == number_of_right_pars) && (n == number_of_right_pars)) { 9 | results.push_back(str); 10 | } 11 | 12 | if (number_of_left_pars < n) { 13 | str.push_back('('); 14 | generate_parenthesis(n, number_of_left_pars + 1, number_of_right_pars, str, results); 15 | str.pop_back(); 16 | } 17 | 18 | if (number_of_right_pars < number_of_left_pars) { 19 | str.push_back(')'); 20 | generate_parenthesis(n, number_of_left_pars, number_of_right_pars + 1, str, results); 21 | str.pop_back(); 22 | } 23 | } 24 | 25 | vector generateParenthesis(int n) { 26 | vector results; 27 | string str; 28 | 29 | generate_parenthesis(n, 0, 0, str, results); 30 | 31 | return results; 32 | } 33 | }; -------------------------------------------------------------------------------- /gray_code.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector grayCode(int n) { 4 | // http://en.wikipedia.org/wiki/Gray_code 5 | vector code; 6 | int size = 1 << n; 7 | 8 | for (int i = 0; i < size; ++i) { 9 | code.push_back((i >> 1) ^ i); 10 | } 11 | 12 | return code; 13 | } 14 | }; -------------------------------------------------------------------------------- /implement_strstr.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | /* 4 | char *strStr(char *haystack, char *needle) { 5 | int h_len = strlen(haystack); 6 | int n_len = strlen(needle); 7 | 8 | if (0 == n_len) { 9 | return haystack; 10 | } 11 | 12 | for (int i = 0; i <= (h_len - n_len); ++i) { 13 | if (0 == strncmp(haystack + i, needle, n_len)) { 14 | return haystack + i; 15 | } 16 | } 17 | 18 | return NULL; 19 | } 20 | */ 21 | 22 | // Using KMP method! 23 | char *strStr(char *haystack, char *needle) { 24 | int h_len = strlen(haystack); 25 | int n_len = strlen(needle); 26 | 27 | if (0 == n_len) { 28 | return haystack; 29 | } 30 | 31 | vector next(n_len); 32 | 33 | generate_next(next, needle); 34 | 35 | for (int i = 0, j = 0; i < h_len; ++i) { 36 | // 算法核心,向前找到匹配位置。 37 | while ((j > 0) && (haystack[i] != needle[j])) { 38 | j = next[j - 1]; 39 | } 40 | 41 | // 如果相等,needle的索引位置往后移动一位。 42 | if (haystack[i] == needle[j]) { 43 | ++j; 44 | } 45 | 46 | if (j == n_len) { 47 | return haystack + i - j + 1; 48 | } 49 | } 50 | 51 | return NULL; 52 | } 53 | 54 | protected: 55 | void generate_next(vector &next, char *needle) { 56 | int n_len = strlen(needle); 57 | 58 | // 因为第一个元素没有前缀后缀,所以永远是0。 59 | next[0] = 0; 60 | 61 | for (int i = 1, j = 0; i < n_len; ++i) { 62 | // j代表部分[0, i]的部分匹配值 63 | // 当i和j指向的字符不匹配时,next向前遍历,直到两个字符相等或j等于0. 64 | while ((j > 0) && (needle[i] != needle[j])) { 65 | j = next[j - 1]; 66 | } 67 | 68 | // 如果i和j指向的字符相等,那么j增加1。 69 | if (needle[i] == needle[j]) { 70 | ++j; 71 | } 72 | 73 | next[i] = j; 74 | } 75 | } 76 | }; -------------------------------------------------------------------------------- /insert_interval.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool merge(Interval &left, Interval &right) { 4 | if ((right.start <= left.start) && (right.end >= left.start)) { 5 | left.start = right.start; 6 | left.end = (left.end > right.end) ? left.end : right.end; 7 | } 8 | else if ((right.start >= left.start) && (right.start <= left.end)) { 9 | left.end = (left.end > right.end) ? left.end : right.end; 10 | } 11 | else { 12 | return false; 13 | } 14 | 15 | return true; 16 | } 17 | 18 | vector insert(vector &intervals, Interval newInterval) { 19 | vector result; 20 | bool inserted = false; 21 | 22 | for (int i = 0; i < intervals.size(); ++i) { 23 | if (!inserted) { 24 | if (merge(newInterval, intervals[i])) { 25 | result.push_back(newInterval); 26 | inserted = true; 27 | } 28 | else { 29 | if (newInterval.end < intervals[i].start) { 30 | result.push_back(newInterval); 31 | inserted = true; 32 | --i; 33 | } 34 | else { 35 | result.push_back(intervals[i]); 36 | } 37 | } 38 | } 39 | else { 40 | int size = result.size(); 41 | 42 | if (!merge(result[size - 1], intervals[i])) { 43 | result.push_back(intervals[i]); 44 | } 45 | } 46 | } 47 | 48 | if (!inserted) { 49 | result.push_back(newInterval); 50 | } 51 | 52 | return result; 53 | } 54 | }; -------------------------------------------------------------------------------- /insertion_sort_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *insertionSortList(ListNode *head) { 4 | ListNode *sorted = NULL; 5 | ListNode *node = NULL; 6 | 7 | while (head != NULL) { 8 | node = head->next; 9 | insert_node(sorted, head); 10 | head = node; 11 | } 12 | 13 | return sorted; 14 | } 15 | 16 | protected: 17 | void insert_node(ListNode *&head, ListNode *&node) { 18 | if (NULL == head) { 19 | head = node; 20 | head->next = NULL; 21 | } 22 | else { 23 | if (node->val <= head->val) { 24 | node->next = head; 25 | head = node; 26 | } 27 | else { 28 | ListNode *prev = NULL; 29 | ListNode *next = head; 30 | 31 | while (next != NULL) { 32 | if (next->val < node->val) { 33 | prev = next; 34 | next = next->next; 35 | } 36 | else { 37 | prev->next = node; 38 | node->next = next; 39 | 40 | return; 41 | } 42 | } 43 | 44 | prev->next = node; 45 | node->next = NULL; 46 | } 47 | } 48 | } 49 | }; -------------------------------------------------------------------------------- /integer_to_roman.cpp: -------------------------------------------------------------------------------- 1 | static const char* quick_check_table[4][9] = {{"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}, // 1 - 9 2 | {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}, // 10 - 90 3 | {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}, // 100 - 900 4 | {"M", "MM", "MMM"}}; // 1000 - 3000 5 | 6 | class Solution { 7 | public: 8 | string intToRoman(int num) { 9 | string roman; 10 | int level = 0; // 个十百千位标记 11 | 12 | while (num > 0) { 13 | int i = num % 10; 14 | 15 | if (i > 0) { 16 | roman = string(quick_check_table[level][i - 1]) + roman; 17 | } 18 | 19 | num /= 10; 20 | ++level; 21 | } 22 | 23 | return roman; 24 | } 25 | }; -------------------------------------------------------------------------------- /interleaving_string.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_interleave(const char *s1, 4 | int s1_index, 5 | const char *s2, 6 | int s2_index, 7 | const char *s3, 8 | vector > &match_statuses) { 9 | if ('\0' == *s1) { 10 | return (0 == strcmp(s2, s3)); 11 | } 12 | else if ('\0' == *s2) { 13 | return (0 == strcmp(s1, s3)); 14 | } 15 | else { 16 | int status = match_statuses[s1_index][s2_index]; 17 | 18 | if (status != 0) { 19 | return (status == 1); 20 | } 21 | 22 | bool match = false; 23 | 24 | if (*s1 == *s3) { 25 | match = is_interleave(s1 + 1, s1_index + 1, s2, s2_index, s3 + 1, match_statuses); 26 | } 27 | 28 | if ((match == false) && (*s2 == *s3)) { 29 | match = is_interleave(s1, s1_index, s2 + 1, s2_index + 1, s3 + 1, match_statuses); 30 | } 31 | 32 | match_statuses[s1_index][s2_index] = match ? 1 : -1; 33 | 34 | return match; 35 | } 36 | } 37 | 38 | bool isInterleave(string s1, string s2, string s3) { 39 | int s1_size = s1.length(); 40 | int s2_size = s2.length(); 41 | int s3_size = s3.length(); 42 | 43 | if ((s1_size + s2_size) != s3_size) { 44 | return false; 45 | } 46 | 47 | // 0: 未初始化 48 | // -1: 未匹配 49 | // 1: 匹配 50 | vector > match_statuses(s1_size, vector(s2_size, 0)); 51 | 52 | return is_interleave(s1.c_str(), 0, s2.c_str(), 0, s3.c_str(), match_statuses); 53 | } 54 | }; -------------------------------------------------------------------------------- /jump_game.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool canJump(int A[], int n) { 4 | vector marks(n, false); 5 | 6 | if (1 == n) { 7 | return true; 8 | } 9 | 10 | marks[0] = (A[0] > 0); 11 | 12 | for (int i = 1; i < n; ++i) { 13 | if (!marks[i]) { 14 | for (int j = i - 1; j >= 0; --j) { 15 | if (marks[j]) { 16 | if ((j + A[j]) >= i) { 17 | marks[i] = true; 18 | break; 19 | } 20 | } 21 | } 22 | } 23 | } 24 | 25 | return marks[n - 1]; 26 | } 27 | }; -------------------------------------------------------------------------------- /jump_game_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int calc_steps(int array[], int target, vector &steps) { 4 | if (-1 != steps[target]) { 5 | return steps[target]; 6 | } 7 | 8 | int min = INT_MAX; 9 | 10 | for (int i = target - 1; i >= 0; --i) { 11 | if ((i + array[i]) >= target) { 12 | // 典型的动态规划啊! 13 | if ((calc_steps(array, i, steps) + 1) < min) { 14 | min = steps[i] + 1; 15 | } 16 | } 17 | } 18 | 19 | steps[target] = min; 20 | 21 | return min; 22 | } 23 | 24 | int jump(int A[], int n) { 25 | vector steps(n, -1); // 每一个点走几步可以到达 26 | 27 | // 初始化steps 28 | steps[0] = 0; 29 | for (int i = 1; i <= min(A[0], n - 1); ++i) { 30 | steps[i] = 1; 31 | } 32 | 33 | calc_steps(A, n - 1, steps); 34 | 35 | return steps[n - 1]; 36 | } 37 | }; -------------------------------------------------------------------------------- /largest_rectangle_in_histogram.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int largestRectangleArea(vector &height) { 4 | int size = height.size(); 5 | 6 | if (0 == size) { 7 | return 0; 8 | } 9 | 10 | int result = INT_MIN; 11 | int index; 12 | stack bars; 13 | 14 | for (int i = 0; i < size; ++i) { 15 | if (!bars.empty()) { 16 | // 如果堆栈顶部的元素比当前的高度高,弹出并计算可能的面积 17 | while ((!bars.empty()) && (height[bars.top()] > height[i])) { 18 | index = bars.top(); 19 | bars.pop(); 20 | 21 | if (bars.empty()) { 22 | result = max(result, i * height[index]); 23 | } 24 | else { 25 | result = max(result, (i - bars.top() - 1) * height[index]); 26 | } 27 | } 28 | } 29 | 30 | // 前面的元素必须小于等于当前元素 31 | bars.push(i); 32 | } 33 | 34 | while (!bars.empty()) { 35 | index = bars.top(); 36 | bars.pop(); 37 | 38 | if (bars.empty()) { 39 | result = max(result, size * height[index]); 40 | } 41 | else { 42 | result = max(result, (size - bars.top() - 1) * height[index]); 43 | } 44 | } 45 | 46 | return result; 47 | } 48 | }; -------------------------------------------------------------------------------- /length_of_last_word.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_alphabets(char c) { 4 | return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); 5 | } 6 | 7 | int lengthOfLastWord(const char *s) { 8 | int len = 0; 9 | bool found = false; 10 | 11 | for (int i = strlen(s) - 1; i >= 0; --i) { 12 | char c = s[i]; 13 | 14 | if (is_alphabets(c)) { 15 | if (!found) { 16 | found = true; 17 | } 18 | 19 | ++len; 20 | } 21 | else { 22 | if (found) { 23 | break; 24 | } 25 | } 26 | } 27 | 28 | return len; 29 | } 30 | }; -------------------------------------------------------------------------------- /letter_combinations_of_a_phone_number.cpp: -------------------------------------------------------------------------------- 1 | static char keys[8][4] = {{'a', 'b', 'c'}, // 2 2 | {'d', 'e', 'f'}, // 3 3 | {'g', 'h', 'i'}, // 4 4 | {'j', 'k', 'l'}, // 5 5 | {'m', 'n', 'o'}, // 6 6 | {'p', 'q', 'r', 's'}, // 7 7 | {'t', 'u', 'v'}, // 8 8 | {'w', 'x', 'y', 'z'}}; // 9 9 | static int sizes[] = {3, 3, 3, 3, 3, 4, 3, 4}; 10 | 11 | class Solution { 12 | public: 13 | vector letterCombinations(string digits) { 14 | vector results; 15 | int levels = digits.size(); // 采用分层遍历法 16 | int current_level = 0; 17 | vector indexes(levels, 0); // 记录每层得状态 18 | 19 | if (0 == levels) { 20 | return vector(1, ""); 21 | } 22 | 23 | // 已234为例,遍历顺序如下 24 | // adg 25 | // adh 26 | // adi 27 | // aeg 28 | // aeh 29 | // aei 30 | // afg 31 | // afh 32 | // afi 33 | // bdg 34 | // bdh 35 | // bdi 36 | // ... 37 | while (true) { 38 | // 键盘2是第0个元素 39 | int c_index = digits[current_level] - '0' - 2; 40 | 41 | if (sizes[c_index] == indexes[current_level]) { 42 | if (0 == current_level) { 43 | // 遍历结束 44 | break; 45 | } 46 | 47 | indexes[current_level] = 0; 48 | --current_level; 49 | ++indexes[current_level]; 50 | 51 | continue; 52 | } 53 | else { 54 | string str; 55 | int i; 56 | 57 | if (current_level < (levels - 1)) { 58 | ++current_level; 59 | } 60 | else { 61 | for (i = 0; i < current_level; ++i) { 62 | str.push_back(keys[digits[i] - '0' - 2][indexes[i]]); 63 | } 64 | 65 | // 占位用 66 | str.push_back('?'); 67 | 68 | for (i = 0; i < sizes[c_index]; ++i) { 69 | str[current_level] = keys[c_index][i]; 70 | 71 | results.push_back(str); 72 | } 73 | 74 | indexes[current_level] = sizes[c_index]; 75 | } 76 | } 77 | } 78 | 79 | return results; 80 | } 81 | }; -------------------------------------------------------------------------------- /linked_list_cycle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool hasCycle(ListNode *head) { 4 | if (NULL == head) { 5 | return false; 6 | } 7 | 8 | ListNode *curr = head; 9 | ListNode *next = head->next; 10 | 11 | while (true) { 12 | curr = curr->next; 13 | 14 | int steps = 0; 15 | 16 | while ((next != NULL) && (steps < 2)) { 17 | next = next->next; 18 | ++steps; 19 | } 20 | 21 | if (NULL == next) { 22 | return false; 23 | } 24 | 25 | if (curr == next) { 26 | return true; 27 | } 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /linked_list_cycle_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *detectCycle(ListNode *head) { 4 | if (NULL == head) { 5 | return false; 6 | } 7 | 8 | ListNode *curr = head; 9 | ListNode *next = head->next; 10 | ListNode *new_head = head->next; 11 | 12 | while (true) { 13 | curr = curr->next; 14 | 15 | int steps = 0; 16 | 17 | while ((next != NULL) && (steps < 2)) { 18 | next = next->next; 19 | ++steps; 20 | } 21 | 22 | if (NULL == next) { 23 | return NULL; 24 | } 25 | 26 | if (curr == next) { 27 | break; 28 | } 29 | } 30 | 31 | next = next->next; 32 | 33 | // new_head的位置等于head往前走圈的长度 34 | while (curr != next) { 35 | new_head = new_head->next; 36 | next = next->next; 37 | } 38 | 39 | // head和new_head的重合点就是 40 | while (head != new_head) { 41 | head = head->next; 42 | new_head = new_head->next; 43 | } 44 | 45 | return head; 46 | } 47 | }; -------------------------------------------------------------------------------- /longest_common_prefix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string longestCommonPrefix(vector &strs) { 4 | if (0 == strs.size()) { 5 | return string(); 6 | } 7 | 8 | int index = 0; 9 | bool stop = false; 10 | 11 | while (!stop) { 12 | char c = '\0'; 13 | 14 | for (vector::const_iterator it = strs.begin(); it != strs.end(); ++it) { 15 | if (index < it->length()) { 16 | if ('\0' == c) { 17 | c = (*it)[index]; 18 | } 19 | else { 20 | if (c != (*it)[index]) { 21 | stop = true; 22 | break; 23 | } 24 | } 25 | } 26 | else { 27 | stop = true; 28 | break; 29 | } 30 | } 31 | 32 | ++index; 33 | } 34 | 35 | return strs[0].substr(0, index - 1); 36 | } 37 | }; -------------------------------------------------------------------------------- /longest_consecutive_sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 这里必须假设hash的操作是O(1)的 4 | int consecutives(unordered_multimap &hash, 5 | int value, 6 | bool ascending) { // true: 升序 false: 降序 7 | int count = 0; 8 | 9 | while (hash.count(value) > 0) { 10 | ++count; 11 | hash.erase(value); // 非常重要! 12 | value += ascending ? 1: (-1); 13 | } 14 | 15 | return count; 16 | } 17 | int longestConsecutive(vector &num) { 18 | int longest = 0; 19 | unordered_multimap hash; 20 | int i; 21 | 22 | for (i = 0; i < num.size(); ++i) { 23 | hash.emplace(num[i], num[i]); 24 | } 25 | 26 | for (i = 0; i < num.size(); ++i) { 27 | if (hash.count(num[i]) > 0) { 28 | longest = max(longest, 29 | consecutives(hash, num[i], false) + 30 | consecutives(hash, num[i] + 1, true)); 31 | } 32 | } 33 | 34 | return longest; 35 | } 36 | }; -------------------------------------------------------------------------------- /longest_palindromic_substring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int extend(const string &str, int start, int end) { 4 | int len = str.length(); 5 | int steps = 0; 6 | 7 | while ((start >= 0) && (end < len)) { 8 | if (str[start] == str[end]) { 9 | --start; 10 | ++end; 11 | ++steps; 12 | } 13 | else { 14 | break; 15 | } 16 | } 17 | 18 | return steps; 19 | } 20 | 21 | string longestPalindrome(string s) { 22 | int start = 0; 23 | int max_len = 0; 24 | 25 | for (int i = 0; i < s.length(); ++i) { 26 | int steps; 27 | int len_of_substr; 28 | 29 | steps = extend(s, i, i + 1); 30 | len_of_substr = steps * 2; 31 | 32 | if (len_of_substr > max_len) { 33 | start = i - steps + 1; 34 | max_len = len_of_substr; 35 | } 36 | 37 | steps = extend(s, i - 1, i + 1); 38 | len_of_substr = steps * 2 + 1; 39 | 40 | if (len_of_substr > max_len) { 41 | start = i - steps; 42 | max_len = len_of_substr; 43 | } 44 | } 45 | 46 | return s.substr(start, max_len); 47 | } 48 | }; -------------------------------------------------------------------------------- /longest_substring_without_repeating_characters.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int lengthOfLongestSubstring(string s) { 4 | int len = s.length(); 5 | int i = 0; 6 | int max_len = 0; 7 | 8 | while (i < len) { 9 | int len_of_substr = 1; 10 | int next = i + 1; 11 | vector marks(256, false); // 记录是否有重复字符出现 12 | 13 | marks[s[i]] = true; 14 | 15 | while (next < len) { 16 | if (marks[s[next]]) { 17 | break; 18 | } 19 | 20 | marks[s[next]] = true; 21 | ++next; 22 | ++len_of_substr; 23 | } 24 | 25 | if (len_of_substr > max_len) { 26 | max_len = len_of_substr; 27 | } 28 | 29 | ++i; 30 | } 31 | 32 | return max_len; 33 | } 34 | }; -------------------------------------------------------------------------------- /longest_valid_parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 原理分析 4 | // 以)(()())为例子: 5 | // 1. 堆栈1:记录当前左括号位置和有效括号对长度 6 | // 2. 最长长度longest = -1。 7 | // 3. 0-): 堆栈1的大小为0,无法匹配,抛弃。 8 | // 4. 1-(: 压入堆栈1,当前长度为0,堆栈1内元素为((1, 0))。 9 | // 5. 2-(: 压入堆栈1,当前长度为0,堆栈1内元素为((1, 0), (2, 0))。 10 | // 6. 3-): 堆栈1的大小大于0,正好可以匹配。弹出一个元素,当前配对长度为(3 - 2 + 0 + 1 = 2),longest = 2。 11 | // 3: 当前右括号位置。 12 | // 2: 当前左括号位置。 13 | // 0: 之前有效括号对长度。 14 | // 1: 索引修正。 15 | // 7. 4-(: 压入堆栈1,当前长度为2,堆栈内元素为((1, 0), (4, 2))。 16 | // 8. 5-): 堆栈1的大小大于0,正好可以匹配。弹出一个元素,当前配对长度为(5 - 4 + 2 + 1 = 4),longest = 4。 17 | int longestValidParentheses(string s) { 18 | int longest = 0; 19 | int current = 0; 20 | int max = - 1; 21 | stack > records; // 记录当前左括号位置和有效括号对长度 22 | 23 | for (int i = 0; i < s.length(); ++i) { 24 | if ('(' == s[i]) { 25 | records.push(pair(i, current)); 26 | current = 0; 27 | } 28 | else { 29 | current = 0; 30 | 31 | if (records.size() > 0) { 32 | pair record = records.top(); 33 | 34 | current = i - record.first + record.second + 1; 35 | records.pop(); 36 | 37 | if (current > longest) { 38 | longest = current; 39 | } 40 | } 41 | } 42 | } 43 | 44 | return longest; 45 | } 46 | }; -------------------------------------------------------------------------------- /lru_cache.cpp: -------------------------------------------------------------------------------- 1 | class LRUCache{ 2 | public: 3 | LRUCache(int capacity) { 4 | _capacity = capacity; 5 | } 6 | 7 | int get(int key) { 8 | if (cache_map.find(key) != cache_map.end()) { 9 | // 把节点移动到最前,同时更新cache_map[key]的位置。 10 | cache_list.splice(cache_list.begin(), cache_list, cache_map[key]); 11 | cache_map[key] = cache_list.begin(); 12 | 13 | return cache_map[key]->_value; 14 | } 15 | else { 16 | return -1; 17 | } 18 | } 19 | 20 | void set(int key, int value) { 21 | if (cache_map.find(key) == cache_map.end()) { 22 | // 找不到key 23 | if (cache_list.size() == _capacity) { 24 | // 客满,删除尾部节点,访问最少。 25 | cache_map.erase(cache_list.back()._key); 26 | cache_list.pop_back(); 27 | } 28 | 29 | cache_list.push_front(_Node(key, value)); 30 | cache_map[key] = cache_list.begin(); 31 | } 32 | else { 33 | // 更新节点值和map对应位置 34 | cache_map[key]->_value = value; 35 | cache_list.splice(cache_list.begin(), cache_list, cache_map[key]); 36 | cache_map[key] = cache_list.begin(); 37 | } 38 | } 39 | 40 | protected: 41 | struct _Node { 42 | int _key; 43 | int _value; 44 | _Node(int key, int value) : _key(key), _value(value) {} 45 | }; 46 | 47 | int _capacity; 48 | list<_Node> cache_list; 49 | map::iterator > cache_map; 50 | }; -------------------------------------------------------------------------------- /max_points_on_a_line.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxPoints(vector &points) { 4 | if (points.size() <= 2) { 5 | return points.size(); 6 | } 7 | 8 | int max_points = INT_MIN; 9 | map lines; 10 | 11 | for (int i = 0; i < (points.size() - 1); ++i) { 12 | int same_points = 0; 13 | int _max_points = 1; 14 | 15 | lines.clear(); 16 | 17 | for (int j = i + 1; j < points.size(); ++j) { 18 | int x = points[i].x - points[j].x; 19 | int y = points[i].y - points[j].y; 20 | double slope = numeric_limits::infinity(); // 偷懒的做法 21 | 22 | if ((0 ==x) && (0 == y)) { 23 | ++same_points; 24 | } 25 | else { 26 | if (y != 0) { 27 | slope = (double)x / (double)y; 28 | } 29 | 30 | int count = (lines.find(slope) != lines.end()) ? lines[slope] + 1: 2; 31 | 32 | lines[slope] = count; 33 | 34 | if (_max_points < count) { 35 | _max_points = count; 36 | } 37 | } 38 | } 39 | 40 | if (max_points < (_max_points + same_points)) { 41 | max_points = _max_points + same_points; 42 | } 43 | } 44 | 45 | return max_points; 46 | } 47 | }; -------------------------------------------------------------------------------- /maximal_rectangle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maximal_rectangle(vector heights) { 4 | // 下面的代码参考largest_rectangle_in_histogram.cpp 5 | // 变量名略作规范 6 | int size = heights.size(); 7 | 8 | if (0 == size) { 9 | return 0; 10 | } 11 | 12 | int result = INT_MIN; 13 | int index; 14 | stack bars; 15 | 16 | for (int i = 0; i < size; ++i) { 17 | if (!bars.empty()) { 18 | // 如果堆栈顶部的元素比当前的高度高,弹出并计算可能的面积 19 | while ((!bars.empty()) && (heights[bars.top()] > heights[i])) { 20 | index = bars.top(); 21 | bars.pop(); 22 | 23 | if (bars.empty()) { 24 | result = max(result, i * heights[index]); 25 | } 26 | else { 27 | result = max(result, (i - bars.top() - 1) * heights[index]); 28 | } 29 | } 30 | } 31 | 32 | // 前面的元素必须小于等于当前元素 33 | bars.push(i); 34 | } 35 | 36 | while (!bars.empty()) { 37 | index = bars.top(); 38 | bars.pop(); 39 | 40 | if (bars.empty()) { 41 | result = max(result, size * heights[index]); 42 | } 43 | else { 44 | result = max(result, (size - bars.top() - 1) * heights[index]); 45 | } 46 | } 47 | 48 | return result; 49 | } 50 | 51 | int maximalRectangle(vector > &matrix) { 52 | if (0 == matrix.size()) { 53 | return 0; 54 | } 55 | 56 | int result = INT_MIN; 57 | int height = matrix.size(); 58 | int width = matrix[0].size(); 59 | int row; 60 | int col; 61 | vector > counts(height, vector(width, 0)); 62 | 63 | for (row = 0; row < height; ++row) { 64 | for (col = 0; col < width; ++col) { 65 | if (matrix[row][col] != '0') { 66 | if (0 == row) { 67 | counts[row][col] = 1; 68 | } 69 | else { 70 | // 每一行往上数,包括自己有几个1。 71 | counts[row][col] = counts[row - 1][col] + 1; 72 | } 73 | } 74 | } 75 | } 76 | 77 | for (row = 0; row < height; ++row) { 78 | result = max(result, maximal_rectangle(counts[row])); 79 | } 80 | 81 | return result; 82 | } 83 | }; -------------------------------------------------------------------------------- /maximum_depth_of_binary_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxDepth(TreeNode *root) { 4 | if (NULL == root) { 5 | return 0; 6 | } 7 | 8 | return 1 + max(maxDepth(root->left), maxDepth(root->right)); 9 | } 10 | }; -------------------------------------------------------------------------------- /maximum_product_subarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProduct(int A[], int n) { 4 | if (1 == n) { 5 | return A[0]; 6 | } 7 | 8 | int max_product; 9 | int positive_max = 0; // 正的最大值 10 | int negtive_min = 0; // 负的最小值 11 | 12 | for (int i = 0; i < n; ++i) { 13 | if (A[i] < 0) { 14 | // 交换,为后面可能遇到的负数做准备 15 | swap(positive_max, negtive_min); 16 | } 17 | 18 | positive_max = max(positive_max * A[i], A[i]); 19 | negtive_min = min(negtive_min * A[i], A[i]); 20 | max_product = max(max_product, positive_max); 21 | } 22 | 23 | return max_product; 24 | } 25 | }; -------------------------------------------------------------------------------- /maximum_subarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxSubArray(int A[], int n) { 4 | int max = INT_MIN; 5 | int i; 6 | int j; 7 | 8 | for (int i = 0; i < n; ) { 9 | int sub_sum = 0; 10 | 11 | j = i; 12 | 13 | do { 14 | sub_sum += A[j]; 15 | 16 | if (sub_sum > max) { 17 | max = sub_sum; 18 | } 19 | 20 | ++j; 21 | } while ((j < n) && (sub_sum > 0)); 22 | 23 | i = j; 24 | } 25 | 26 | return max; 27 | } 28 | }; -------------------------------------------------------------------------------- /median_of_two_sorted_arrays.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int find_kth_number(int array_a[], int start_of_a, int end_of_a, int array_b[], int start_of_b, int end_of_b, int k) { 4 | if (start_of_a > end_of_a) { 5 | return array_b[start_of_b + k - 1]; 6 | } 7 | else if (start_of_b > end_of_b) { 8 | return array_a[start_of_a + k - 1]; 9 | } 10 | else { 11 | int mid_of_a = (start_of_a + end_of_a) / 2; 12 | int mid_of_b = (start_of_b + end_of_b) / 2; 13 | int len_of_first_half_of_a = mid_of_a - start_of_a + 1; 14 | int len_of_first_half_of_b = mid_of_b - start_of_b + 1; 15 | int len_of_first_half = len_of_first_half_of_a + len_of_first_half_of_b; 16 | 17 | if (len_of_first_half > k) { 18 | if (array_a[mid_of_a] > array_b[mid_of_b]) { 19 | // 第k个数在a的前半部分和b的全部里找 20 | return find_kth_number(array_a, 21 | start_of_a, 22 | mid_of_a - 1, 23 | array_b, 24 | start_of_b, 25 | end_of_b, 26 | k); 27 | } 28 | else { 29 | // 第k个数在b的前半部分和a的全部里找 30 | return find_kth_number(array_a, 31 | start_of_a, 32 | end_of_a, 33 | array_b, 34 | start_of_b, 35 | mid_of_b - 1, 36 | k); 37 | } 38 | } 39 | else { 40 | if (array_a[mid_of_a] > array_b[mid_of_b]) { 41 | // 第k个数在a的全部和b的后半部分找 42 | return find_kth_number(array_a, 43 | start_of_a, 44 | end_of_a, 45 | array_b, 46 | mid_of_b + 1, 47 | end_of_b, 48 | k - (len_of_first_half_of_b)); 49 | } 50 | else { 51 | // 第k个数在b的全部和a的后半部分找 52 | return find_kth_number(array_a, mid_of_a + 1, end_of_a, array_b, start_of_b, end_of_b, k - (len_of_first_half_of_a)); 53 | } 54 | } 55 | } 56 | } 57 | 58 | double findMedianSortedArrays(int A[], int m, int B[], int n) { 59 | bool even = (((m + n) % 2) == 0); // 判断总数是否为偶数。 60 | int mid = even ? (m + n) / 2 : (m + n) /2 + 1; // 中间数位置 61 | 62 | int v_1 = find_kth_number(A, 0, m - 1, B, 0, n - 1, mid); 63 | 64 | if (!even) { 65 | return v_1; 66 | } 67 | else { 68 | int v_2 = find_kth_number(A, 0, m - 1, B, 0, n - 1, mid + 1); 69 | 70 | return (double)(v_1 + v_2) / 2.0f; 71 | } 72 | } 73 | }; -------------------------------------------------------------------------------- /merge_intervals.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool merge(Interval &left, Interval &right) { 4 | if ((right.start <= left.start) && (right.end >= left.start)) { 5 | left.start = right.start; 6 | left.end = (left.end > right.end) ? left.end : right.end; 7 | } 8 | else if ((right.start >= left.start) && (right.start <= left.end)) { 9 | left.end = (left.end > right.end) ? left.end : right.end; 10 | } 11 | else { 12 | return false; 13 | } 14 | 15 | return true; 16 | } 17 | 18 | vector merge(vector &intervals) { 19 | vector result; 20 | 21 | for (int i = 0; i < intervals.size(); ++i) { 22 | for (int j = result.size() - 1; j >= 0; --j) { 23 | if (merge(intervals[i], result[j])) { 24 | result.erase(result.begin() + j); 25 | } 26 | } 27 | 28 | result.push_back(intervals[i]); 29 | } 30 | 31 | return result; 32 | } 33 | }; -------------------------------------------------------------------------------- /merge_k_sorted_lists.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode* merge_two_lists(ListNode *list_1, ListNode *list_2) { 4 | ListNode *head = NULL; 5 | ListNode *tail = NULL; 6 | ListNode *tmp = NULL; 7 | 8 | while ((list_1 != NULL) && (list_2 != NULL)) { 9 | if (list_1->val < list_2->val) { 10 | tmp = list_1; 11 | list_1 = list_1->next; 12 | } 13 | else { 14 | tmp = list_2; 15 | list_2 = list_2->next; 16 | } 17 | 18 | if (NULL == head) { 19 | head = tmp; 20 | tail = tmp; 21 | } 22 | else { 23 | tail->next = tmp; 24 | tail = tmp; 25 | } 26 | } 27 | 28 | tmp = (NULL == list_1) ? list_2 : list_1; 29 | 30 | if (head != NULL) { 31 | tail->next = tmp; 32 | 33 | return head; 34 | } 35 | else { 36 | return tmp; 37 | } 38 | } 39 | 40 | ListNode *mergeKLists(vector &lists) { 41 | if (0 == lists.size()) { 42 | return NULL; 43 | } 44 | 45 | ListNode *head = lists[0]; 46 | 47 | for (int i = 1; i < lists.size(); ++i) { 48 | head = merge_two_lists(head, lists[i]); 49 | } 50 | 51 | return head; 52 | } 53 | }; -------------------------------------------------------------------------------- /merge_sorted_array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void merge(int A[], int m, int B[], int n) { 4 | int i = m - 1; 5 | int j = n - 1; 6 | int k = m + n - 1; 7 | 8 | while ((i >= 0) && (j >= 0)) { 9 | if (A[i] > B[j]) { 10 | A[k] = A[i]; 11 | --i; 12 | } 13 | else { 14 | A[k] = B[j]; 15 | --j; 16 | } 17 | 18 | --k; 19 | } 20 | 21 | if (j >= 0) { 22 | memcpy(A, B, (j + 1) * sizeof(int)); 23 | } 24 | } 25 | }; -------------------------------------------------------------------------------- /merge_two_sorted_lists.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { 4 | ListNode *head = NULL; 5 | ListNode *tail = NULL; 6 | ListNode *tmp; 7 | 8 | while ((l1 != NULL) && (l2 != NULL)) { 9 | if (l1->val < l2->val) { 10 | tmp = l1; 11 | l1 = l1->next; 12 | } 13 | else { 14 | tmp = l2; 15 | l2 = l2->next; 16 | } 17 | 18 | if (NULL == head) { 19 | head = tmp; 20 | tail = tmp; 21 | } 22 | 23 | tail->next = tmp; 24 | tail = tmp; 25 | } 26 | 27 | tmp = (NULL == l1) ? l2 : l1; 28 | if (tail != NULL) { 29 | tail->next = tmp; 30 | } 31 | else { 32 | head = tmp; 33 | } 34 | 35 | return head; 36 | } 37 | }; -------------------------------------------------------------------------------- /minimum_depth_of_binary_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minDepth(TreeNode *root) { 4 | if (NULL == root) { 5 | return 0; 6 | } 7 | 8 | int depth = INT_MAX; 9 | 10 | if (root->left != NULL) { 11 | depth = minDepth(root->left); 12 | } 13 | 14 | if (root->right != NULL) { 15 | depth = min(depth, minDepth(root->right)); 16 | } 17 | 18 | return (INT_MAX == depth) ? 1 : depth + 1; 19 | } 20 | }; -------------------------------------------------------------------------------- /minimum_path_sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minPathSum(vector > &grid) { 4 | int rows = grid.size(); 5 | 6 | if (0 == rows) { 7 | return 0; 8 | } 9 | 10 | int cols = grid[0].size(); 11 | int row; 12 | int col; 13 | 14 | for (row = 1; row < rows; ++row) { 15 | grid[row][0] += grid[row - 1][0]; 16 | } 17 | 18 | for (col = 1; col < cols; ++col) { 19 | grid[0][col] += grid[0][col - 1]; 20 | } 21 | 22 | for (row = 1; row < rows; ++row) { 23 | for (col = 1; col < cols; ++col) { 24 | grid[row][col] += min(grid[row - 1][col], grid[row][col - 1]); 25 | } 26 | } 27 | 28 | return grid[rows - 1][cols - 1]; 29 | } 30 | }; -------------------------------------------------------------------------------- /minimum_window_substring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string minWindow(string S, string T) { 4 | int min_window = INT_MAX; 5 | int start; 6 | vector target(256, 0); // 字符串T的字符统计 7 | vector status(256, 0); 8 | int i; 9 | int j; 10 | int matched = 0; // 已匹配的字符数 11 | int s_len = S.length(); 12 | int t_len = T.length(); 13 | 14 | for (i = 0; i < t_len; ++i) { 15 | ++target[T[i]]; 16 | } 17 | 18 | for (i = 0, j = 0; i < s_len; ++i) { 19 | if (matched < t_len) { 20 | if (status[S[i]] < target[S[i]]) { 21 | ++matched; 22 | } 23 | 24 | ++status[S[i]]; 25 | } 26 | 27 | if (matched == t_len) { 28 | // 从头开始看哪些字符可以删除 29 | while ((j <= i) && (status[S[j]] > target[S[j]])) { 30 | --status[S[j]]; 31 | ++j; 32 | } 33 | 34 | // 修正min_window 35 | if (min_window > (i - j + 1)) { 36 | min_window = i - j + 1; 37 | // 新字符串的开始位置 38 | start = j; 39 | } 40 | 41 | // 继续去除字符,直到matched小于t_len 42 | while ((j <= i) && (matched == t_len)) { 43 | --status[S[j]]; 44 | 45 | if (status[S[j]] < target[S[j]]) { 46 | --matched; 47 | } 48 | 49 | ++j; 50 | } 51 | } 52 | } 53 | 54 | return (min_window != INT_MAX) ? S.substr(start, min_window) : ""; 55 | } 56 | }; -------------------------------------------------------------------------------- /multiply_strings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string multiply(string num1, string num2) { 4 | if (("0" == num1) || ("0" == num2)) { 5 | return "0"; 6 | } 7 | 8 | // 模仿竖式乘法 9 | string result = ""; 10 | int i; 11 | int j; 12 | int flag = 0; // 进位标记 13 | int steps = 0; // 移位数,用来表示十百千万... 14 | 15 | for (i = num1.length() - 1; i >= 0; --i) { 16 | int position = steps; // 结果数组当前的位置 17 | 18 | for (j = num2.length() - 1; j >= 0; --j) { 19 | int val = (num1[i] - '0') * (num2[j] - '0') + flag; 20 | 21 | if (position < result.length()) { 22 | val += result[position] - '0'; 23 | result[position] = (val % 10) + '0'; 24 | } 25 | else { 26 | result.append(1, (val % 10) + '0'); 27 | } 28 | 29 | flag = val / 10; 30 | ++position; 31 | } 32 | 33 | // 单独处理最后一个进位 34 | if (flag > 0) { 35 | result.append(1, flag + '0'); 36 | } 37 | 38 | flag = 0; 39 | ++steps; 40 | } 41 | 42 | reverse(result.begin(), result.end()); 43 | 44 | return result; 45 | } 46 | }; -------------------------------------------------------------------------------- /n_queens.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void solve_queens(int total_rows, 4 | int curr_row, 5 | vector &solution, 6 | vector > &results) { 7 | int row; 8 | int col; 9 | 10 | if (curr_row == total_rows) { 11 | vector strs(total_rows); 12 | 13 | for (row = 0; row < total_rows; ++row) { 14 | strs[row].append(solution[row], '.'); 15 | strs[row].append(1, 'Q'); 16 | strs[row].append(total_rows - solution[row] - 1, '.'); 17 | } 18 | 19 | results.push_back(strs); 20 | } 21 | else { 22 | // 按列做检查 23 | for (col = 0; col < total_rows; ++col) { 24 | for (row = 0; row < curr_row; ++row) { 25 | // 不能在同一列上 26 | if (col == solution[row]) { 27 | break; 28 | } 29 | 30 | // 不能在相同的对角线上 31 | if (abs(curr_row - row) == abs(col - solution[row])) { 32 | break; 33 | } 34 | } 35 | 36 | if (row == curr_row) { 37 | solution[row] = col; 38 | solve_queens(total_rows, row + 1, solution, results); 39 | } 40 | } 41 | } 42 | } 43 | 44 | vector > solveNQueens(int n) { 45 | vector > results; 46 | vector solution(n); 47 | 48 | solve_queens(n, 0, solution, results); 49 | 50 | return results; 51 | } 52 | }; -------------------------------------------------------------------------------- /n_queens_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void total_n_queens(int total_rows, 4 | int curr_row, 5 | vector &solution, 6 | int &result) { 7 | int row; 8 | int col; 9 | 10 | if (curr_row == total_rows) { 11 | ++result; 12 | } 13 | else { 14 | for (col = 0; col < total_rows; ++col) { 15 | for (row = 0; row < curr_row; ++row) { 16 | if (col == solution[row]) { 17 | break; 18 | } 19 | 20 | if (abs(curr_row - row) == abs(col - solution[row])) { 21 | break; 22 | } 23 | } 24 | 25 | if (row == curr_row) { 26 | solution[row] = col; 27 | total_n_queens(total_rows, row + 1, solution, result); 28 | } 29 | } 30 | } 31 | } 32 | 33 | int totalNQueens(int n) { 34 | int result = 0; 35 | vector solution(n); 36 | 37 | total_n_queens(n, 0, solution, result); 38 | 39 | return result; 40 | } 41 | }; -------------------------------------------------------------------------------- /next_permutation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 原理分析 4 | // 以162543为例,下一个应该是163245 5 | // 步骤如下: 6 | // 1. 找到最后一个num[i] < num[i + 1]的点。 7 | // 2. 如果第一步没找到,说明已经是最后一个排练,直接逆序返回即可。 8 | // 3. 从num[i + 1]到num[size - 1]找到大于num[i]的最小的数,并与num[i]交换位置。 9 | // 4. 对num[i + 1]到num[size - 1]排序。 10 | void nextPermutation(vector &num) { 11 | int size =num.size(); 12 | int first_index = -1; 13 | int second_index = -1; 14 | int min = INT_MAX; 15 | int i; 16 | 17 | if (size <= 1) { 18 | return; 19 | } 20 | 21 | for (i = 0; i < (size - 1); ++i) { 22 | if (num[i] < num[i + 1]) { 23 | first_index = i; 24 | } 25 | } 26 | 27 | if (-1 == first_index) { 28 | reverse(num.begin(), num.end()); 29 | } 30 | else { 31 | for (i = first_index + 1; i < size; ++i) { 32 | if (num[i] > num[first_index]) { 33 | if (num[i] < min) { 34 | min = num[i]; 35 | second_index = i; 36 | } 37 | } 38 | } 39 | 40 | swap(num[first_index], num[second_index]); 41 | sort(num.begin() + first_index + 1, num.end()); 42 | } 43 | } 44 | }; -------------------------------------------------------------------------------- /palindrome_number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isPalindrome(int x) { 4 | if (x < 0) { 5 | return false; 6 | } 7 | 8 | int y = x; 9 | int z = 0; 10 | 11 | while (y > 0) { 12 | z = z * 10 + (y % 10); 13 | y /= 10; 14 | } 15 | 16 | return z == x; 17 | } 18 | }; -------------------------------------------------------------------------------- /palindrome_partitioning.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 动态规划 4 | // 判断s[i, j]是否为回文的方法: 5 | // 1. s[i + 1, j - 1]是否为回文 6 | // 2. 如果1成了,判断s[i]是否等于s[j]。 7 | vector> partition(string s) { 8 | vector > result; 9 | vector solution; 10 | int len = s.length(); 11 | 12 | if (0 == len) { 13 | return result; 14 | } 15 | 16 | vector > pal_statuses(len, vector(len, 0)); 17 | 18 | _partition(s, 0, solution, result, pal_statuses); 19 | 20 | return result; 21 | } 22 | 23 | protected: 24 | void _partition(string &s, 25 | int start, 26 | vector &solution, 27 | vector > &result, 28 | vector > &pal_statuses) { 29 | int len = s.length(); 30 | 31 | if (start >= len) { 32 | result.push_back(solution); 33 | } 34 | else { 35 | for (int i = start; i < len; ++i) { 36 | if (is_palindrome(s, start, i, pal_statuses)) { 37 | solution.push_back(s.substr(start, i - start + 1)); 38 | _partition(s, i + 1, solution, result, pal_statuses); 39 | solution.pop_back(); 40 | } 41 | } 42 | } 43 | } 44 | 45 | bool is_palindrome(string &s, 46 | int start, 47 | int end, 48 | vector > &pal_statuses) { 49 | if (start >= end) { 50 | if (start == end) { 51 | pal_statuses[start][end] = 1; 52 | } 53 | 54 | return true; 55 | } 56 | else { 57 | if (pal_statuses[start][end] != 0) { 58 | return (pal_statuses[start][end] > 0); 59 | } 60 | else { 61 | if (s[start] != s[end]) { 62 | pal_statuses[start][end] = -1; 63 | 64 | return false; 65 | } 66 | else { 67 | if (is_palindrome(s, start + 1, end - 1, pal_statuses)) { 68 | pal_statuses[start][end] = 1; 69 | } 70 | else { 71 | pal_statuses[start][end] = -1; 72 | } 73 | } 74 | 75 | return (pal_statuses[start][end] > 0); 76 | } 77 | } 78 | } 79 | }; -------------------------------------------------------------------------------- /palindrome_partitioning_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minCut(string s) { 4 | int len = s.length(); 5 | 6 | vector cuts(len + 1); 7 | vector > pal_statuses(len, vector(len, false)); 8 | 9 | for (int i = 0; i <= len; ++i) { 10 | // 从第i个元素开始后面最多可以切几次 11 | cuts[i] = len - i; 12 | } 13 | 14 | for (int i = len - 1; i >= 0; --i) { 15 | for (int j = i; j < len; ++j) { 16 | if ((s[i] == s[j]) && 17 | (((j - i) <= 1) || (pal_statuses[i + 1][j - 1]))) { 18 | pal_statuses[i][j] = true; 19 | // 因为s[i, j]是回文,所以1 + cuts[j + 1]有可能是更好选择 20 | cuts[i] = min(cuts[i], 1 + cuts[j + 1]); 21 | } 22 | } 23 | } 24 | 25 | return cuts[0] - 1; 26 | } 27 | }; -------------------------------------------------------------------------------- /partition_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void insert_node(ListNode *&head, ListNode *&tail, ListNode *node) { 4 | if (NULL == head) { 5 | head = node; 6 | } 7 | else { 8 | tail->next = node; 9 | } 10 | 11 | tail = node; 12 | } 13 | 14 | ListNode *partition(ListNode *head, int x) { 15 | if (NULL == head) { 16 | return NULL; 17 | } 18 | 19 | ListNode *lt_head = NULL; 20 | ListNode *lt_tail = NULL; 21 | ListNode *ge_head = NULL; 22 | ListNode *ge_tail = NULL; 23 | 24 | while (head != NULL) { 25 | if (head->val < x) { 26 | insert_node(lt_head, lt_tail, head); 27 | } 28 | else { 29 | insert_node(ge_head, ge_tail, head); 30 | } 31 | 32 | head = head->next; 33 | } 34 | 35 | if (ge_tail != NULL) { 36 | ge_tail->next = NULL; 37 | } 38 | 39 | if (NULL == lt_head) { 40 | return ge_head; 41 | } 42 | else { 43 | lt_tail->next = ge_head; 44 | 45 | return lt_head; 46 | } 47 | } 48 | }; -------------------------------------------------------------------------------- /pascals_triangle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > generate(int numRows) { 4 | vector > triangle; 5 | 6 | if (numRows <= 0) { 7 | return triangle; 8 | } 9 | 10 | triangle.push_back(vector(1, 1)); 11 | 12 | for (int row = 1; row < numRows; ++row) { 13 | triangle.push_back(vector(row + 1)); 14 | triangle[row][0] = 1; 15 | triangle[row][row] = 1; 16 | 17 | for (int col = 1; col < row; ++col) { 18 | triangle[row][col] = triangle[row - 1][col - 1] + triangle[row - 1][col]; 19 | } 20 | } 21 | 22 | return triangle; 23 | } 24 | }; -------------------------------------------------------------------------------- /pascals_triangle_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector getRow(int rowIndex) { 4 | vector row(rowIndex + 1, 1); 5 | 6 | for (int i = 1; i <= rowIndex; ++i) { 7 | for (int j = i - 1; j > 0; --j) { 8 | row[j] += row[j - 1]; 9 | } 10 | } 11 | 12 | return row; 13 | } 14 | }; -------------------------------------------------------------------------------- /path_sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool hasPathSum(TreeNode *root, int sum) { 4 | if (NULL == root) { 5 | return false; 6 | } 7 | 8 | sum -= root->val; 9 | 10 | if ((NULL == root->left) && (NULL == root->right)) { 11 | return (0 == sum); 12 | } 13 | 14 | return (hasPathSum(root->left, sum) || hasPathSum(root->right, sum)); 15 | } 16 | }; -------------------------------------------------------------------------------- /path_sum_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void path_sum(TreeNode *root, 4 | int sum, 5 | vector &path, 6 | vector > &pathes) { 7 | if (NULL == root) { 8 | return; 9 | } 10 | else { 11 | if ((NULL == root->left) && (NULL == root->right)) { 12 | if (root->val == sum) { 13 | path.push_back(sum); 14 | pathes.push_back(path); 15 | path.pop_back(); 16 | } 17 | } 18 | else { 19 | path.push_back(root->val); 20 | 21 | if (root->left != NULL) { 22 | path_sum(root->left, sum - root->val, path, pathes); 23 | } 24 | 25 | if (root->right != NULL) { 26 | path_sum(root->right, sum - root->val, path, pathes); 27 | } 28 | 29 | path.pop_back(); 30 | } 31 | } 32 | } 33 | 34 | vector > pathSum(TreeNode *root, int sum) { 35 | vector > pathes; 36 | vector path; 37 | 38 | path_sum(root, sum, path, pathes); 39 | 40 | return pathes; 41 | } 42 | }; -------------------------------------------------------------------------------- /permutation_sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string getPermutation(int n, int k) { 4 | string result; 5 | vector digits(n, 1); 6 | vector factors(n, 1); // 记录阶乘结果 7 | int i; 8 | 9 | // 初始化数字和阶乘表 10 | for (i = 1; i < n; ++i) { 11 | digits[i] = i + 1; 12 | factors[i] = i * factors[i - 1]; 13 | } 14 | 15 | for (i = n - 1; i >= 0; --i) { 16 | // 确定第一个数字的位置 17 | int pos = (k - 1) / factors[i]; 18 | 19 | result.push_back(digits[pos] + '0'); 20 | digits.erase(digits.begin() + pos); 21 | k -= (pos * factors[i]); 22 | } 23 | 24 | return result; 25 | } 26 | }; -------------------------------------------------------------------------------- /permutations.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void generate_permutation(vector &num, 4 | int index, 5 | vector &permutation, 6 | vector > &results) { 7 | int size = num.size(); 8 | 9 | if (size == index) { 10 | results.push_back(permutation); 11 | } 12 | else { 13 | for (int i = index; i < size; ++i) { 14 | swap(num[index], num[i]); 15 | permutation.push_back(num[index]); 16 | generate_permutation(num, index + 1, permutation, results); 17 | permutation.pop_back(); 18 | swap(num[index], num[i]); 19 | } 20 | } 21 | } 22 | 23 | vector > permute(vector &num) { 24 | vector > results; 25 | vector permutation; 26 | 27 | generate_permutation(num, 0, permutation, results); 28 | 29 | return results; 30 | } 31 | }; -------------------------------------------------------------------------------- /permutations_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 原理分析 4 | // 标准的排列组合就不说了,典型的递归求解。 5 | // 现在要求不重复,以[1, 1, 2, 3]为例 6 | // [1], [1, 2, 3] 7 | // - [1, 1], [2, 3] 8 | // - [1, 1, 2], [3] => [1, 1, 2, 3] 9 | // - [1, 1, 3], [2] => [1, 1, 3, 2] 10 | // 重新排序,还原成[1, 1, 2, 3] 11 | // [2], [1, 1, 3] 12 | // - [2, 1], [1, 3] 13 | // - [2, 1, 1], [3] => [2, 1, 1, 3] 14 | // - [2, 1, 3], [1] => [2, 1, 3, 1] 15 | // 重新排序,还原成[1, 1, 2, 3] 16 | // [3], [1, 1, 2] 17 | // - [3, 1], [1, 2] 18 | // - [3, 1, 1], [2] => [3, 1, 1, 2] 19 | // - [3, 1, 2], [1] => [3, 1, 2, 1] 20 | void generate_permutation_unique(vector &num, 21 | int index, 22 | vector &permutation, 23 | vector > &results) { 24 | int size = num.size(); 25 | 26 | if (size == index) { 27 | results.push_back(permutation); 28 | } 29 | else { 30 | for (int i = index; i < size; ++i) { 31 | if ((i > index) && (num[i] == num[index])) { 32 | continue; 33 | } 34 | else { 35 | swap(num[index], num[i]); 36 | } 37 | 38 | permutation.push_back(num[index]); 39 | generate_permutation_unique(num, index + 1, permutation, results); 40 | permutation.pop_back(); 41 | } 42 | 43 | sort(num.begin() + index, num.end()); 44 | } 45 | } 46 | 47 | vector > permuteUnique(vector &num) { 48 | vector > results; 49 | vector permutation; 50 | 51 | sort(num.begin(), num.end()); 52 | generate_permutation_unique(num, 0, permutation, results); 53 | 54 | return results; 55 | } 56 | }; -------------------------------------------------------------------------------- /plus_one.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector plusOne(vector &digits) { 4 | vector result; 5 | int flag = 1; 6 | int sum; 7 | 8 | for (int i = digits.size() - 1; i >= 0; --i) { 9 | sum = digits[i] + flag; 10 | result.push_back(sum % 10); 11 | flag = sum / 10; 12 | } 13 | 14 | if (flag > 0) { 15 | result.push_back(1); 16 | } 17 | 18 | reverse(result.begin(), result.end()); 19 | 20 | return result; 21 | } 22 | }; -------------------------------------------------------------------------------- /populating_next_right_pointers_in_each_node.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void connect(TreeLinkNode *root) { 4 | if (NULL == root) { 5 | return; 6 | } 7 | 8 | if (root->left != NULL) { 9 | root->left->next = root->right; 10 | } 11 | 12 | if (root->right != NULL) { 13 | root->right->next = (root->next != NULL) ? root->next->left : NULL; 14 | } 15 | 16 | connect(root->left); 17 | connect(root->right); 18 | } 19 | }; -------------------------------------------------------------------------------- /populating_next_right_pointers_in_each_node_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void connect(TreeLinkNode *root) { 4 | if (NULL == root) { 5 | return; 6 | } 7 | 8 | TreeLinkNode *node = root->next; 9 | TreeLinkNode *next = NULL; 10 | 11 | while (node != NULL) { 12 | if ((node->left != NULL) || (node->right != NULL)) { 13 | next = (node->left != NULL) ? node->left : node->right; 14 | break; 15 | } 16 | else { 17 | node = node->next; 18 | } 19 | } 20 | 21 | if (root->left != NULL) { 22 | root->left->next = (root->right != NULL) ? root->right : next; 23 | } 24 | 25 | if (root->right != NULL) { 26 | root->right->next = next; 27 | } 28 | 29 | // 必须先右子树,不然左子树最右节点的next会不知道指向哪里。 30 | connect(root->right); 31 | connect(root->left); 32 | } 33 | }; -------------------------------------------------------------------------------- /pow_x_n.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double pow(double x, int n) { 4 | if (0 == n) { 5 | return (double)1.0; 6 | } 7 | else if (1 == n) { 8 | return x; 9 | } 10 | else { 11 | double result; 12 | int abs_n = abs(n); 13 | 14 | if ((abs_n % 2) == 0) { 15 | // 偶数 16 | result = pow(x, abs_n / 2); 17 | result *= result; 18 | } 19 | else { 20 | // 奇数数 21 | result = pow(x, abs_n / 2); 22 | result *= result; 23 | result *= x; 24 | } 25 | 26 | return (n >= 0) ? result : (double)1.0 / result; 27 | } 28 | } 29 | }; -------------------------------------------------------------------------------- /questions.txt: -------------------------------------------------------------------------------- 1 | 152. Maximum Product Subarray 2 | 151. Reverse Words in a String 3 | 150. Evaluate Reverse Polish Notation 4 | 149. Max Points on a Line 5 | 148. Sort List 6 | 147. Insertion Sort List 7 | 146. LRU Cache 8 | 145. Binary Tree Postorder Traversal 9 | 144. Binary Tree Preorder Traversal 10 | 143. Reorder List 11 | 142. Linked List Cycle II 12 | 141. Linked List Cycle 13 | 140. Word Break II 14 | 139. Word Break 15 | 138. Copy List with Random Pointer 16 | 137. Single Number II 17 | 136. Single Number 18 | 135. Candy 19 | 134. Gas Station 20 | 133. Clone Graph 21 | 132. Palindrome Partitioning II 22 | 131. Palindrome Partitioning 23 | 130. Surrounded Regions 24 | 129. Sum Root to Leaf Numbers 25 | 128. Longest Consecutive Sequence 26 | 127. Word Ladder II 27 | 126. Word Ladder 28 | 125. Valid Palindrome 29 | 124. Binary Tree Maximum Path Sum 30 | 123. Best Time to Buy and Sell Stock III 31 | 122. Best Time to Buy and Sell Stock II 32 | 121. Best Time to Buy and Sell Stock 33 | 120. Triangle 34 | 119. Pascal's Triangle II 35 | 118. Pascal's Triangle 36 | 117. Populating Next Right Pointers in Each Node II 37 | 116. Populating Next Right Pointers in Each Node 38 | 115. Distinct Subsequences 39 | 114. Flatten Binary Tree to Linked List 40 | 113. Path Sum II 41 | 112. Path Sum 42 | 111. Minimum Depth of Binary Tree 43 | 110. Balanced Binary Tree 44 | 109. Convert Sorted List to Binary Search Tree 45 | 108. Convert Sorted Array to Binary Search Tree 46 | 107. Binary Tree Level Order Traversal II 47 | 106. Construct Binary Tree from Inorder and Postorder Traversal 48 | 105. Construct Binary Tree from Preorder and Inorder Traversal 49 | 104. Maximum Depth of Binary Tree 50 | 103. Binary Tree Zigzag Level Order Traversal 51 | 102. Binary Tree Level Order Traversal 52 | 101. Symmetric Tree 53 | 100. Same Tree 54 | 99. Recover Binary Search Tree 55 | 98. Validate Binary Search Tree 56 | 97. Interleaving String 57 | 96. Unique Binary Search Trees II 58 | 95. Unique Binary Search Trees 59 | 94. Binary Tree Inorder Traversal 60 | 93. Restore IP Addresses 61 | 92. Reverse Linked List II 62 | 91. Subsets II 63 | 90. Decode Ways 64 | 89. Gray Code 65 | 88. Merge Sorted Array 66 | 87. Scramble String 67 | 86. Partition List 68 | 85. Maximal Rectangle 69 | 84. Largest Rectangle in Histogram 70 | 83. Remove Duplicates from Sorted List II 71 | 82. Remove Duplicates from Sorted List 72 | 81. Search in Rotated Sorted Array II 73 | 80. Remove Duplicates from Sorted Array II 74 | 79. Word Search 75 | 78. Subsets 76 | 77. Combinations 77 | 76. Minimum Window Substring 78 | 75. Sort Colors 79 | 74. Search a 2D Matrix 80 | 73. Set Matrix Zeroes 81 | 72. Edit Distance 82 | 71. Simplify Path 83 | 70. Climbing Stairs 84 | 69. Sqrt(x) 85 | 68. Text Justification 86 | 67. Plus One 87 | 66. Valid Number 88 | 65. Add Binary 89 | 64. Merge Two Sorted Lists 90 | 63. Minimum Path Sum 91 | 62. Unique Paths II 92 | 61: Unique Paths 93 | 60. Rotate List 94 | 59. Permutation Sequence 95 | 58. Spiral Matrix II 96 | 57. Length of Last Word 97 | 56. Insert Interval 98 | 55. Merge Intervals 99 | 54. Jump Game 100 | 53. Spiral Matrix 101 | 52. Maximum Subarray 102 | 51. N-Queens II 103 | 50. N-Queens 104 | 49. Pow(x, n) 105 | 48. Anagrams 106 | 47. Rotate Image 107 | 46. Permutations II 108 | 45. Permutations 109 | 44. Jump Game II 110 | 43. Wildcard Matching 111 | 42. Multiply Strings 112 | 41. Trapping Rain Water 113 | 40. First Missing Positive 114 | 39. Combination Sum II 115 | 38. Combination Sum 116 | 37. Count and Say 117 | 36. Sudoku Solver 118 | 35. Valid Sudoku 119 | 34. Search Insert Position 120 | 33. Search for a Range 121 | 32. Search in Rotated Sorted Array 122 | 31. Longest Valid Parentheses 123 | 30. Next Permutation 124 | 29. Substring with Concatenation of All Words 125 | 28. Divide Two Integers 126 | 27. Implement strStr() 127 | 26. Remove Element 128 | 25. Remove Duplicates from Sorted Array 129 | 24. Reverse Nodes in k-Group 130 | 23. Swap Nodes in Pairs 131 | 22. Merge k Sorted Lists 132 | 21. Generate Parentheses 133 | 20. Valid Parentheses 134 | 19. Remove Nth Node From End of List 135 | 18. Letter Combinations of a Phone Number 136 | 17. 4Sum 137 | 16. 3Sum Closest 138 | 15. 3Sum 139 | 14. Longest Common Prefix 140 | 13. Roman to Integer 141 | 12. Integer to Roman 142 | 11. Container With Most Water 143 | 10. Regular Expression Matching 144 | 9. Palindrome Number 145 | 8. String to Integer (atoi) 146 | 7. Reverse Integer 147 | 6. ZigZag Conversion 148 | 5. Longest Palindromic Substring 149 | 4. Add Two Numbers 150 | 3. Longest Substring Without Repeating Characters 151 | 2. Median of Two Sorted Arrays 152 | 1. Two Sum -------------------------------------------------------------------------------- /recover_binary_search_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 最简单的例子 4 | // 3 5 | // \ 6 | // 2 7 | // \ 8 | // 1 9 | // 把1,3交换就可以了。 10 | // 1. in_order(3->left) 11 | // 2. _parent = 3 12 | // 3. 3->right = 2, inorder(2) 13 | // 4. inorder(2->left) 14 | // 5. root = 2, 3 > 2 => _first = 3, _second = 2, _parent = 2 15 | // 6. in_order(2->right) 16 | // 7. in_order(1->left) 17 | // 8. root = 1, 2 > 1 => _second = 1) 18 | void in_order(TreeNode *root) { 19 | if (NULL == root) { 20 | return; 21 | } 22 | else { 23 | // 先推到最左边的节点 24 | in_order(root->left); 25 | 26 | if (NULL == _parent) { 27 | _parent = root; 28 | } 29 | else { 30 | // 因为是中序遍历,_parent在root左面,这两个节可能需要交换。 31 | if (_parent->val > root->val) { 32 | if (NULL == _first) { 33 | _first = _parent; 34 | } 35 | 36 | _second = root; 37 | } 38 | 39 | // _parent提升到当前层 40 | _parent = root; 41 | } 42 | 43 | in_order(root->right); 44 | } 45 | } 46 | 47 | void recoverTree(TreeNode *root) { 48 | _parent = NULL; 49 | _first = NULL; 50 | _second = NULL; 51 | 52 | in_order(root); 53 | 54 | swap(_first->val, _second->val); 55 | } 56 | 57 | protected: 58 | TreeNode *_parent; // _first和_second的最近公共父节点 59 | TreeNode *_first; 60 | TreeNode *_second; 61 | }; -------------------------------------------------------------------------------- /regular_expression_matching.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isMatch(const char *s, const char *p) { 4 | if ('\0' == *p) { 5 | return '\0' == *s; 6 | } 7 | 8 | if ('*' == *(p + 1)) { 9 | while ((*s != '\0') && ((*s == *p) || ('.' == *p))) { 10 | if (isMatch(s, p + 2)) { 11 | return true; 12 | } 13 | 14 | ++s; 15 | } 16 | 17 | return isMatch(s, p + 2); 18 | } 19 | else { 20 | if ((*s != '\0') && ((*s == *p) || ('.' == *p))) { 21 | return isMatch(s + 1, p + 1); 22 | } 23 | } 24 | 25 | return false; 26 | } 27 | }; -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int removeDuplicates(int A[], int n) { 4 | int steps; 5 | 6 | for (int i = 1; i < n; ++i) { 7 | if (A[i] == A[i - 1]) { 8 | ++steps; 9 | } 10 | else { 11 | A[i - steps] = A[i]; 12 | } 13 | } 14 | 15 | return n - steps; 16 | } 17 | }; -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_array_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int removeDuplicates(int A[], int n) { 4 | int count = n; 5 | int dup = 1; // 相同的数字最多出现2次 6 | int steps = 0; 7 | 8 | for (int i = 1; i < n; ++i) { 9 | if (A[i] == A[i - 1]) { 10 | ++dup; 11 | 12 | if (dup <= 2) { 13 | A[i - steps] = A[i]; 14 | } 15 | else { 16 | ++steps; 17 | --count; // 这个数要删除 18 | } 19 | } 20 | else { 21 | dup = 1; 22 | A[i - steps] = A[i]; 23 | } 24 | } 25 | 26 | return count; 27 | } 28 | }; -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *deleteDuplicates(ListNode *head) { 4 | if (NULL == head) { 5 | return NULL; 6 | } 7 | 8 | ListNode *curr = head; 9 | ListNode *next = head->next; 10 | 11 | while (next != NULL) { 12 | if (curr->val != next->val) { 13 | curr->next = next; 14 | curr = next; 15 | } 16 | 17 | next = next->next; 18 | } 19 | 20 | curr->next = NULL; 21 | 22 | return head; 23 | } 24 | }; -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_list_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void insert_node(ListNode *&head, ListNode *&tail, ListNode *node) { 4 | if (NULL == head) { 5 | head = node; 6 | } 7 | else { 8 | tail->next = node; 9 | } 10 | 11 | tail = node; 12 | } 13 | 14 | ListNode *deleteDuplicates(ListNode *head) { 15 | if (NULL == head) { 16 | return NULL; 17 | } 18 | 19 | ListNode *new_head = NULL; 20 | ListNode *new_tail = NULL; 21 | ListNode *node = head->next; 22 | int count = 1; 23 | 24 | while (node != NULL) { 25 | if (head->val != node->val) { 26 | if (1 == count) { 27 | insert_node(new_head, new_tail, head); 28 | } 29 | 30 | head = node; 31 | count = 1; 32 | } 33 | else { 34 | ++count; 35 | } 36 | 37 | node = node->next; 38 | } 39 | 40 | if ((head != NULL) && (1 == count)) { 41 | insert_node(new_head, new_tail, head); 42 | } 43 | 44 | if (new_tail != NULL) { 45 | new_tail->next = NULL; 46 | } 47 | 48 | return new_head; 49 | } 50 | }; -------------------------------------------------------------------------------- /remove_element.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int removeElement(int A[], int n, int elem) { 4 | int count = 0; 5 | 6 | for (int i = 0; i < n; ++i) { 7 | if (A[i] == elem) { 8 | ++count; 9 | } 10 | else { 11 | A[i - count] = A[i]; 12 | } 13 | } 14 | 15 | return n - count; 16 | } 17 | }; -------------------------------------------------------------------------------- /remove_nth_node_from_end_of_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *removeNthFromEnd(ListNode *head, int n) { 4 | ListNode *list_1 = head; 5 | ListNode *list_2 = head; 6 | ListNode *prev = NULL; 7 | 8 | // 请仔细阅读题目 9 | for (int i = 1; i < n; ++i) { 10 | list_2 = list_2->next; 11 | } 12 | 13 | while (true) { 14 | // list_2现在位于最后一个元素 15 | if (NULL == list_2->next) { 16 | break; 17 | } 18 | 19 | prev = list_1; // 记住前一个元素的位置 20 | list_1 = list_1->next; 21 | list_2 = list_2->next; 22 | } 23 | 24 | // 执行删除操作 25 | if (prev != NULL) { 26 | prev->next = list_1->next; 27 | 28 | return head; 29 | } 30 | else { 31 | // 如果prev是NULL说明head就是要删除的元素 32 | return list_1->next; 33 | } 34 | } 35 | }; -------------------------------------------------------------------------------- /reorder_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void reorderList(ListNode *head) { 4 | if ((NULL == head) || (NULL == head->next)) { 5 | return; 6 | } 7 | 8 | int len = 0; // 计算链表长度 9 | ListNode *node = head; 10 | 11 | while (node != NULL) { 12 | ++len; 13 | node = node->next; 14 | } 15 | 16 | // 把链表从当中拆分成两个链表 17 | int cut_point = (len + 1) / 2; 18 | int i = 1; 19 | ListNode *head_1 = head; 20 | ListNode *head_2 = NULL; 21 | 22 | node = head_1; 23 | 24 | while (true) { 25 | if (i == cut_point) { 26 | head_2 = node->next; 27 | node->next = NULL; 28 | 29 | break; 30 | } 31 | else { 32 | node = node->next; 33 | ++i; 34 | } 35 | } 36 | 37 | head_2 = reverse_list(head_2); 38 | 39 | // 合并head_1和head_2 40 | while (head_2 != NULL) { 41 | node = head_1->next; 42 | head_1->next = head_2; 43 | head_2 = head_2->next; 44 | head_1->next->next = node; 45 | head_1 = node; 46 | 47 | if (NULL == head_1) { 48 | break; 49 | } 50 | } 51 | } 52 | 53 | protected: 54 | ListNode* reverse_list(ListNode* head) { 55 | ListNode *new_head = NULL; 56 | ListNode *new_tail = NULL; 57 | 58 | while (head != NULL) { 59 | if (NULL == new_head) { 60 | new_head = head; 61 | new_tail = head; 62 | head = head->next; 63 | new_tail->next = NULL; 64 | } 65 | else { 66 | ListNode *node = head->next; 67 | 68 | head->next = new_head; 69 | new_head = head; 70 | head = node; 71 | } 72 | } 73 | 74 | return new_head; 75 | } 76 | }; -------------------------------------------------------------------------------- /restore_ip_addresses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void split_string(string &s, 4 | int index, 5 | vector &segments, 6 | vector &ips) { 7 | if ((4 == segments.size()) && ('\0' == s[index])) { 8 | string ip = ""; 9 | 10 | for (int i = 0; i < 4; ++i) { 11 | ip += segments[i]; 12 | 13 | if (i < 3) { 14 | ip += "."; 15 | } 16 | } 17 | 18 | ips.push_back(ip); 19 | } 20 | else { 21 | if ((segments.size() >= 4) && ('\0' != s[index])) { 22 | return; 23 | } 24 | 25 | for (int len = 1; (index + len) <= s.length(); ++len) { 26 | string segment = s.substr(index, len); 27 | int v = atoi(segment.c_str()); 28 | 29 | if (v <= 255) { 30 | // x.0.x可以,x.0??.x不可以 31 | if ((segment.length() > 1) && ('0' == segment[0])) { 32 | continue; 33 | } 34 | 35 | segments.push_back(segment); 36 | split_string(s, index + len, segments, ips); 37 | segments.pop_back(); 38 | } 39 | else { 40 | break; 41 | } 42 | } 43 | } 44 | } 45 | 46 | vector restoreIpAddresses(string s) { 47 | vector ips; 48 | vector segments; 49 | 50 | split_string(s, 0, segments, ips); 51 | 52 | return ips; 53 | } 54 | }; -------------------------------------------------------------------------------- /reverse_integer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int reverse(int x) { 4 | bool minus = (x < 0); // 是否负数 5 | int result = 0; 6 | 7 | x = abs(x); 8 | 9 | while (x > 0) { 10 | result = result * 10 + x % 10; 11 | x /= 10; 12 | } 13 | 14 | return minus ? -result : result; 15 | } 16 | }; -------------------------------------------------------------------------------- /reverse_linked_list_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *reverseBetween(ListNode *head, int m, int n) { 4 | ListNode *next_start = head; 5 | ListNode *prev = NULL; 6 | int i = 0; 7 | int j = 0; 8 | 9 | if (m == n) { 10 | return head; 11 | } 12 | 13 | // 向前走到第m个节点 14 | while (i < (m - 1)) { 15 | prev = next_start; 16 | next_start = next_start->next; 17 | ++i; 18 | } 19 | 20 | // 反转m到n的区间 21 | ListNode *new_head = NULL; 22 | ListNode *new_tail = NULL; 23 | 24 | while (j <= (n - m)) { 25 | if (NULL == new_head) { 26 | new_head = next_start; 27 | new_tail = next_start; 28 | next_start = next_start->next; 29 | } 30 | else { 31 | ListNode *tmp = next_start; 32 | next_start = next_start->next; 33 | tmp->next = new_head; 34 | new_head = tmp; 35 | } 36 | 37 | ++j; 38 | } 39 | 40 | if (new_tail != NULL) { 41 | new_tail->next = next_start; 42 | } 43 | 44 | if (prev != NULL) { 45 | prev->next = new_head; 46 | 47 | return head; 48 | } 49 | else { 50 | return new_head; 51 | } 52 | } 53 | }; -------------------------------------------------------------------------------- /reverse_nodes_in_k_group.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *reverseKGroup(ListNode *head, int k) { 4 | if (1 == k) { 5 | return head; 6 | } 7 | 8 | ListNode *p = head; 9 | ListNode *prev = NULL; 10 | 11 | while (p != NULL) { 12 | ListNode *first_node = p; 13 | ListNode *kth_node = first_node; 14 | 15 | for (int i = 1; i < k; ++i) { 16 | kth_node = kth_node->next; 17 | 18 | if (NULL == kth_node) { 19 | if (prev != NULL) { 20 | prev->next = first_node; 21 | } 22 | 23 | return head; 24 | } 25 | } 26 | 27 | if (NULL == prev) { 28 | head = kth_node; 29 | } 30 | 31 | p = kth_node->next; 32 | 33 | ListNode *tmp_head = NULL; 34 | ListNode *tmp_tail = NULL; 35 | ListNode *tmp = NULL; 36 | 37 | while (first_node != kth_node) { 38 | tmp = first_node->next; 39 | 40 | if (NULL == tmp_head) { 41 | tmp_head = first_node; 42 | tmp_tail = first_node; 43 | tmp_tail->next = NULL; 44 | } 45 | else { 46 | first_node->next = tmp_head; 47 | tmp_head = first_node; 48 | } 49 | 50 | first_node = tmp; 51 | } 52 | 53 | kth_node->next = tmp_head; 54 | tmp_head = kth_node; 55 | 56 | if (prev != NULL) { 57 | prev->next = tmp_head; 58 | } 59 | 60 | prev = tmp_tail; 61 | } 62 | 63 | return head; 64 | } 65 | }; -------------------------------------------------------------------------------- /reverse_words_in_a_string.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void reverseWords(string &s) { 4 | reverse(s.begin(), s.end()); 5 | 6 | string result; 7 | int len = s.length(); 8 | int i = 0; 9 | 10 | // 跳过起始的空格 11 | while ((i < len) && (' ' == s[i])) { 12 | ++i; 13 | } 14 | 15 | for ( ; i < len; ) { 16 | int j = 0; // 单词的长度 17 | 18 | while (((i + j) < len) && (s[i + j] != ' ')) 19 | { 20 | ++j; 21 | } 22 | 23 | if (j >= 1) { 24 | if (!result.empty()) { 25 | result.push_back(' '); 26 | } 27 | 28 | for (int k = i + j - 1; k >= i; --k) { 29 | result.push_back(s[k]); 30 | } 31 | } 32 | 33 | i += j; 34 | 35 | // 继续跳空格 36 | while ((i < len) && (' ' == s[i])) { 37 | ++i; 38 | } 39 | } 40 | 41 | s = result; 42 | } 43 | }; -------------------------------------------------------------------------------- /roman_to_integer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int romanToInt(string s) { 4 | int result = 0; 5 | int mul = 0; // 处理个十百千位 6 | char one; 7 | char five; 8 | char ten; 9 | const char *str = s.c_str(); 10 | 11 | while (*str != '\0') { 12 | char c = *str; 13 | 14 | if ('M' == c) { 15 | // 1000 16 | mul = 1000; 17 | one = 'M'; 18 | five = '?'; 19 | ten = '?'; 20 | } 21 | else if (('C' == c) || ('D' == c)) { 22 | // 100 23 | mul = 100; 24 | one = 'C'; 25 | five = 'D'; 26 | ten = 'M'; 27 | } 28 | else if (('X' == c) || ('L' == c)) { 29 | // 10 30 | mul = 10; 31 | one = 'X'; 32 | five = 'L'; 33 | ten = 'C'; 34 | } 35 | else { 36 | // 1 37 | mul = 1; 38 | one = 'I'; 39 | five = 'V'; 40 | ten = 'X'; 41 | } 42 | 43 | int tmp; 44 | 45 | if (one == c) { 46 | tmp = 1; 47 | ++str; 48 | 49 | while ((*str != '\0') && (one == *str)) { 50 | ++tmp; 51 | ++str; 52 | } 53 | 54 | if (ten == *str) { 55 | result += (mul * 9); 56 | ++str; 57 | } 58 | else if (five == *str) { 59 | result += (mul * 4); 60 | ++str; 61 | } 62 | else { 63 | result += (mul * tmp); 64 | } 65 | } 66 | else if (five == c) { 67 | tmp = 5; 68 | ++str; 69 | 70 | while ((*str != '\0') && (one == *str)) { 71 | ++tmp; 72 | ++str; 73 | } 74 | 75 | result += (mul * tmp); 76 | } 77 | } 78 | 79 | return result; 80 | } 81 | }; -------------------------------------------------------------------------------- /rotate_image.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void rotate(vector > &matrix) { 4 | int n = matrix.size(); 5 | 6 | if (n <= 1) { 7 | return; 8 | } 9 | 10 | int top = 0; 11 | int bottom = n - 1; 12 | int left = 0; 13 | int right = n - 1; 14 | 15 | while ((top < bottom) && (left < right)) { 16 | int steps = right - left + 1; 17 | 18 | for (int i = left; i < right; ++i) { 19 | int tmp = matrix[top][i]; 20 | 21 | steps = i - left; 22 | matrix[top][i] = matrix[bottom - steps][left]; 23 | matrix[bottom -steps][left] = matrix[bottom][right - steps]; 24 | matrix[bottom][right - steps] = matrix[top + steps][right]; 25 | matrix[top + steps][right] = tmp; 26 | } 27 | 28 | ++top; 29 | --bottom; 30 | ++left; 31 | --right; 32 | } 33 | } 34 | }; -------------------------------------------------------------------------------- /rotate_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int get_list_len(ListNode *head) { 4 | int len = 0; 5 | 6 | while (head != NULL) { 7 | head = head->next; 8 | ++len; 9 | } 10 | 11 | return len; 12 | } 13 | 14 | ListNode *rotateRight(ListNode *head, int k) { 15 | if (NULL == head) { 16 | return head; 17 | } 18 | 19 | // 小心k比链表长度大的情况 20 | k %= get_list_len(head); 21 | if (0 == k) { 22 | return head; 23 | } 24 | 25 | ListNode *first = head; 26 | ListNode *second = head; 27 | int i = 0; 28 | 29 | // second前进k步 30 | while (i < k) { 31 | second = second->next; 32 | ++i; 33 | } 34 | 35 | // 一起前进 36 | while (second->next != NULL) { 37 | first = first->next; 38 | second = second->next; 39 | } 40 | 41 | second->next = head; 42 | head = first->next; 43 | first->next = NULL; 44 | 45 | return head; 46 | } 47 | }; -------------------------------------------------------------------------------- /same_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isSameTree(TreeNode *p, TreeNode *q) { 4 | if ((NULL == p) && (NULL == q)) { 5 | return true; 6 | } 7 | else if ((NULL == p) || (NULL == q)) { 8 | return false; 9 | } 10 | else { 11 | if (p->val == q->val) { 12 | return (isSameTree(p->left, q->left) && 13 | isSameTree(p->right, q->right)); 14 | } 15 | else { 16 | return false; 17 | } 18 | } 19 | } 20 | }; -------------------------------------------------------------------------------- /scramble_string.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isScramble(string s1, string s2) { 4 | if (s1.length() != s2.length()) { 5 | return false; 6 | } 7 | 8 | int len = s1.length(); 9 | vector > > scramble_status(len, vector >(len, vector(len))); 10 | int i; 11 | int j; 12 | int k; 13 | int sub_len; 14 | 15 | // 先对长度为1的子串进行判定并保存结果, 16 | // 然后对字串长度不断增加,直到等于len, 17 | // 利用递推算出结果。 18 | for (i = 0; i < len; ++i) { 19 | for (j = 0; j < len; ++j) { 20 | scramble_status[0][i][j] = (s1[i] == s2[j]); 21 | } 22 | } 23 | 24 | for (sub_len = 2; sub_len <= len; ++sub_len) { 25 | for (i = len - sub_len; i >= 0; --i) { 26 | for (j = len - sub_len; j >= 0; --j) { 27 | bool scramble = false; 28 | 29 | for (k = 1; (k < sub_len) && !scramble; ++k) { 30 | scramble = scramble_status[k - 1][i][j] && scramble_status[sub_len - k - 1][i + k][j + k]; 31 | scramble = scramble || (scramble_status[k - 1][i][j + sub_len - k] && scramble_status[sub_len - k - 1][i + k][j]); 32 | } 33 | 34 | scramble_status[sub_len - 1][i][j] = scramble; 35 | } 36 | } 37 | } 38 | 39 | return scramble_status[len - 1][0][0]; 40 | } 41 | }; -------------------------------------------------------------------------------- /search_a_2d_matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool binary_search(vector &row, int target) { 4 | int min = 0; 5 | int max = row.size() - 1; 6 | 7 | while (min <= max) { 8 | int mid = (min + max) / 2; 9 | 10 | if (row[mid] == target) { 11 | return true; 12 | } 13 | else if (row[mid] < target) { 14 | min = mid + 1; 15 | } 16 | else { 17 | max = mid - 1; 18 | } 19 | } 20 | 21 | return false; 22 | } 23 | 24 | // 确定在哪一行搜索 25 | int locate_row(const vector > &matrix, int target) { 26 | int rows = matrix.size(); 27 | 28 | for (int row = 0; row < (rows - 1); ++row) { 29 | if ((target >= matrix[row][0]) && (target < matrix[row + 1][0])) { 30 | return row; 31 | } 32 | } 33 | 34 | return (target >= matrix[rows - 1][0]) ? (rows - 1) : -1; 35 | } 36 | 37 | bool searchMatrix(vector > &matrix, int target) { 38 | int row = locate_row(matrix, target); 39 | 40 | if (row != -1) { 41 | return binary_search(matrix[row], target); 42 | } 43 | else { 44 | return false; 45 | } 46 | } 47 | }; -------------------------------------------------------------------------------- /search_for_a_range.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int binary_search(int array[], int start, int end, int target) { 4 | while (start <= end) { 5 | int mid = (start + end) / 2; 6 | 7 | if (array[mid] < target) { 8 | start = mid + 1; 9 | } 10 | else if (array[mid] > target) { 11 | end = mid - 1; 12 | } 13 | else { 14 | return mid; 15 | } 16 | } 17 | 18 | return -1; 19 | } 20 | 21 | vector searchRange(int A[], int n, int target) { 22 | vector result(2, -1); 23 | int position = binary_search(A, 0, n - 1, target); 24 | 25 | if (-1 == position) { 26 | return result; 27 | } 28 | 29 | int tmp = position - 1; 30 | result[0] = position; 31 | result[1] = position; 32 | 33 | // 搜索[0, position - 1] 34 | while (tmp >= 0) { 35 | tmp = binary_search(A, 0, tmp, target); 36 | 37 | if (-1 == tmp) { 38 | break; 39 | } 40 | else { 41 | result[0] = tmp; // 可能的开始位置 42 | --tmp; 43 | } 44 | } 45 | 46 | tmp = position + 1; 47 | 48 | // 搜索后半段 49 | while (tmp < n) { 50 | tmp = binary_search(A, tmp, n - 1, target); 51 | 52 | if (-1 == tmp) { 53 | break; 54 | } 55 | else { 56 | result[1] = tmp; // 可能的结束位置 57 | ++tmp; 58 | } 59 | } 60 | 61 | return result; 62 | } 63 | }; -------------------------------------------------------------------------------- /search_in_rotated_sorted_array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 原理分析 4 | // 以4567012里找6为例子: 5 | // 判断数组是否顺序,满足条件直接二分法。 6 | // 寻找分界(pivotal)点,满足a[i] < a[i - 1]并且a[i] > a[i + 1]。 7 | // 比较要找的数和A[0],大的话在[0, i - 1]区间找,小的话在[i, n - 1]区间找。 8 | int find_pivotal(int array[], int start, int end) { 9 | if (start >= end) { 10 | return start; 11 | } 12 | 13 | int mid = (start + end) / 2; 14 | 15 | if (array[mid] >= array[start]) { 16 | if (array[mid] >= array[0]) { 17 | return find_pivotal(array, mid + 1, end); 18 | } 19 | else { 20 | return find_pivotal(array, start, mid - 1); 21 | } 22 | } 23 | else { 24 | return find_pivotal(array, start, mid); 25 | } 26 | } 27 | 28 | int binary_search(int array[], int start, int end, int target) { 29 | while (start <= end) { 30 | int mid = (start + end) / 2; 31 | 32 | if (array[mid] < target) { 33 | start = mid + 1; 34 | } 35 | else if (array[mid] > target) { 36 | end = mid - 1; 37 | } 38 | else { 39 | return mid; 40 | } 41 | } 42 | 43 | return -1; 44 | } 45 | 46 | int search(int A[], int n, int target) { 47 | // 处理顺序和只有一个元素的情况 48 | if (A[0] <= A[n - 1]) { 49 | return binary_search(A, 0, n - 1, target); 50 | } 51 | 52 | int pivotal = find_pivotal(A, 0, n - 1); 53 | 54 | if (target >= A[0]) { 55 | return binary_search(A, 0, pivotal - 1, target); 56 | } 57 | else { 58 | return binary_search(A, pivotal, n - 1, target); 59 | } 60 | } 61 | }; -------------------------------------------------------------------------------- /search_in_rotated_sorted_array_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool binary_search(int array[], int start, int end, int target) { 4 | if (start > end) { 5 | return false; 6 | } 7 | 8 | int mid = (start + end) / 2; 9 | bool found = false; 10 | 11 | if (array[mid] == target) { 12 | return true; 13 | } 14 | else if (array[mid] < target) { 15 | if (array[start] <= target) { 16 | found = binary_search(array, start, mid - 1, target); 17 | } 18 | 19 | if (found) { 20 | return true; 21 | } 22 | 23 | found = binary_search(array, mid + 1, end, target); 24 | 25 | if (found) { 26 | return true; 27 | } 28 | } 29 | else { 30 | found = binary_search(array, start, mid - 1, target); 31 | 32 | if (found) { 33 | return true; 34 | } 35 | 36 | if (array[end] >= target) { 37 | found = binary_search(array, mid + 1, end, target); 38 | } 39 | 40 | if (found) { 41 | return true; 42 | } 43 | } 44 | 45 | return false; 46 | } 47 | 48 | bool search(int A[], int n, int target) { 49 | return binary_search(A, 0, n - 1, target); 50 | } 51 | }; -------------------------------------------------------------------------------- /search_insert_position.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int searchInsert(int A[], int n, int target) { 4 | int start = 0; 5 | int end = n - 1; 6 | int mid; 7 | 8 | while (start <= end) { 9 | mid = (start + end) / 2; 10 | 11 | if (A[mid] == target) { 12 | return mid; 13 | } 14 | else if (A[mid] < target) { 15 | start = mid + 1; 16 | } 17 | else { 18 | end = mid - 1; 19 | } 20 | } 21 | 22 | return (A[mid] > target) ? mid : mid + 1; 23 | } 24 | }; -------------------------------------------------------------------------------- /set_matrix_zeroes.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void setZeroes(vector > &matrix) { 4 | if (0 == matrix.size()) { 5 | return; 6 | } 7 | 8 | bool set_first_row = false; // 第一行是否要被清零 9 | bool set_first_col = false; // 第一列是否要被清零 10 | int height = matrix.size(); 11 | int width = matrix[0].size(); 12 | int row; 13 | int col; 14 | 15 | for (col = 0; col < width; ++col) { 16 | if (0 == matrix[0][col]) { 17 | set_first_row = true; 18 | break; 19 | } 20 | } 21 | 22 | for (row = 0; row < height; ++row) { 23 | if (0 == matrix[row][0]) { 24 | set_first_col = true; 25 | break; 26 | } 27 | } 28 | 29 | // 从第二行第二列开始扫描,如果某元素为0,把所在行和列的第一个元素置0. 30 | for (row = 1; row < height; ++row) { 31 | for (col = 1; col < width; ++col) { 32 | if (0 == matrix[row][col]) { 33 | matrix[0][col] = 0; 34 | matrix[row][0] = 0; 35 | } 36 | } 37 | } 38 | 39 | // 扫描第一行,如果元素为0,把所在列清零。 40 | for (col = 1; col < width; ++col) { 41 | if (0 == matrix[0][col]) { 42 | for (row = 1; row < height; ++row) { 43 | matrix[row][col] = 0; 44 | } 45 | } 46 | } 47 | 48 | // 扫描第一列,如果元素为0,把所在行清零。 49 | for (row = 1; row < height; ++row) { 50 | if (0 == matrix[row][0]) { 51 | for (col = 1; col < width; ++col) { 52 | matrix[row][col] = 0; 53 | } 54 | } 55 | } 56 | 57 | // 判断第一行和第一列是否需要清零 58 | if (set_first_row) { 59 | for (col = 0; col < width; ++col) { 60 | matrix[0][col] = 0; 61 | } 62 | } 63 | 64 | if (set_first_col) { 65 | for (row = 0; row < height; ++row) { 66 | matrix[row][0] = 0; 67 | } 68 | } 69 | } 70 | }; -------------------------------------------------------------------------------- /simplify_path.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string simplifyPath(string path) { 4 | string simplified_path = "/"; 5 | vector paths; 6 | int i = 0; 7 | int j; 8 | int len; 9 | 10 | while (path[i] != '\0') { 11 | if ('/' == path[i]) { 12 | // 目录往下一级 13 | ++i; 14 | } 15 | else { 16 | j = i + 1; 17 | 18 | while ((j < path.length()) && (path[j] != '/')) { 19 | ++j; 20 | } 21 | 22 | // 目录段的长度 23 | len = j - i; 24 | 25 | string dir = path.substr(i, len); 26 | 27 | if (dir != ".") { 28 | if (".." == dir) { 29 | if (!paths.empty()) { 30 | // "../"回退到上一层目录 31 | paths.pop_back(); 32 | } 33 | } 34 | else { 35 | paths.push_back(dir); 36 | } 37 | } 38 | else { 39 | // "./"表示当前目录,直接忽略。 40 | } 41 | 42 | i = j; 43 | } 44 | } 45 | 46 | if (paths.size() > 0) { 47 | for (i = 0; i < (paths.size() - 1); ++i) { 48 | simplified_path += paths[i]; 49 | simplified_path += "/"; 50 | } 51 | 52 | simplified_path += paths[i]; 53 | } 54 | 55 | return simplified_path; 56 | } 57 | }; -------------------------------------------------------------------------------- /single_number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int singleNumber(int A[], int n) { 4 | int result = A[0]; 5 | 6 | for (int i = 1; i < n; ++i) { 7 | result ^= A[i]; 8 | } 9 | 10 | return result; 11 | } 12 | }; -------------------------------------------------------------------------------- /single_number_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int singleNumber(int A[], int n) { 4 | int one = 0; // 该bit出现1时置1 5 | int two = 0; // 该bit出现2次1时置1 6 | int xthree; // 当该bit在one和two上都是1时,置0,否则置1 7 | 8 | for (int i = 0; i < n; ++i) { 9 | two |= (one & A[i]); 10 | one ^= A[i]; 11 | xthree = ~(one & two); 12 | one &= xthree; 13 | two &= xthree; 14 | } 15 | 16 | return one; 17 | } 18 | }; -------------------------------------------------------------------------------- /sort_colors.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void sortColors(int A[], int n) { 4 | const int RED = 0; 5 | const int WHITE = 1; 6 | const int BLUE = 2; 7 | int red_index = 0; 8 | int blue_index = n - 1; 9 | int i = 0; 10 | 11 | // 思路就是把红的放到前面,蓝的放到后面。 12 | while (i <= blue_index) { 13 | int color = A[i]; 14 | 15 | if (RED == color) { 16 | swap(A[i], A[red_index]); 17 | 18 | ++i; 19 | ++red_index; // 下次发现红色可以放置的位置 20 | } 21 | else if (BLUE == color) { 22 | swap(A[i], A[blue_index]); 23 | 24 | --blue_index; // 下次发现蓝色可以放置的位置 25 | 26 | // 先不要动i,因为i的位置上有可能出现红色,可以继续像前放置。 27 | } 28 | else { 29 | // 白色不动 30 | ++i; 31 | } 32 | } 33 | } 34 | }; -------------------------------------------------------------------------------- /sort_list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *sortList(ListNode *head) { 4 | return split_and_merge(head); 5 | } 6 | 7 | protected: 8 | ListNode* split_and_merge(ListNode* head) { 9 | if ((NULL == head) || (NULL == head->next)) { 10 | return head; 11 | } 12 | 13 | ListNode *node_1 = head; 14 | ListNode *node_2 = head; 15 | 16 | while ((node_2->next != NULL) && (node_2->next->next != NULL)) { 17 | node_1 = node_1->next; 18 | node_2 = node_2->next->next; 19 | } 20 | 21 | ListNode *head_1 = head; 22 | ListNode *head_2 = node_1->next; 23 | 24 | node_1->next = NULL; 25 | 26 | head_1 = split_and_merge(head_1); 27 | head_2 = split_and_merge(head_2); 28 | 29 | return merge(head_1, head_2); 30 | } 31 | 32 | ListNode* merge(ListNode *node_1, ListNode* node_2) { 33 | ListNode *head = NULL; 34 | ListNode *tail = NULL; 35 | ListNode *node = NULL; 36 | 37 | while ((node_1 != NULL) && (node_2 != NULL)) { 38 | if (node_1->val > node_2->val) { 39 | node = node_2; 40 | node_2 = node_2->next; 41 | } 42 | else { 43 | node = node_1; 44 | node_1 = node_1->next; 45 | } 46 | 47 | if (NULL == head) { 48 | head = node; 49 | } 50 | else { 51 | tail->next = node; 52 | } 53 | 54 | tail = node; 55 | tail->next = NULL; 56 | } 57 | 58 | node = (node_1 != NULL) ? node_1 : node_2; 59 | 60 | if (tail != NULL) { 61 | tail->next = node; 62 | } 63 | 64 | return (head != NULL) ? head : node; 65 | } 66 | }; -------------------------------------------------------------------------------- /spiral_matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector spiralOrder(vector > &matrix) { 4 | vector result; 5 | int height = matrix.size(); 6 | int width; 7 | 8 | if (0 == height) { 9 | return result; 10 | } 11 | 12 | width = matrix[0].size(); 13 | 14 | int top = 0; 15 | int down = height - 1; 16 | int left = 0; 17 | int right = width - 1; 18 | 19 | while ((top <= down) && (left <= right)) { 20 | int i; 21 | 22 | // 上 23 | for (i = left; i <= right; ++i) { 24 | result.push_back(matrix[top][i]); 25 | } 26 | 27 | // 右 28 | for (i = top + 1; i < down; ++i) { 29 | result.push_back(matrix[i][right]); 30 | } 31 | 32 | // 下 33 | if (top < down) { 34 | for (i = right; i >= left; --i) { 35 | result.push_back(matrix[down][i]); 36 | } 37 | } 38 | 39 | // 左 40 | if (left < right) { 41 | for (i = down - 1; i > top; --i) { 42 | result.push_back(matrix[i][left]); 43 | } 44 | } 45 | 46 | ++top; 47 | --down; 48 | ++left; 49 | --right; 50 | } 51 | 52 | return result; 53 | } 54 | }; -------------------------------------------------------------------------------- /spiral_matrix_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > generateMatrix(int n) { 4 | vector > result(n, vector(n)); 5 | int i = 1; 6 | int top = 0; 7 | int down = n - 1; 8 | int left = 0; 9 | int right = n - 1; 10 | 11 | while ((top <= down) && (left <= right)) { 12 | int row; 13 | int col; 14 | 15 | // 上 16 | for (col = left; col <= right; ++col) { 17 | result[top][col] = i; 18 | ++i; 19 | } 20 | 21 | // 右 22 | for (row = top + 1; row < down; ++row) { 23 | result[row][right] = i; 24 | ++i; 25 | } 26 | 27 | // 下 28 | if (top < down) { 29 | for (col = right; col >= left; --col) { 30 | result[down][col] = i; 31 | ++i; 32 | } 33 | } 34 | 35 | // 左 36 | if (left < right) { 37 | for (row = down - 1; row > top; --row) { 38 | result[row][left] = i; 39 | ++i; 40 | } 41 | } 42 | 43 | ++top; 44 | --down; 45 | ++left; 46 | --right; 47 | } 48 | 49 | return result; 50 | } 51 | }; -------------------------------------------------------------------------------- /sqrt_x.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_overflow(int dividend, int divisor, int result) { 4 | return (dividend / divisor) != result; 5 | } 6 | 7 | int sqrt(int x) { 8 | int result; 9 | int min = 0; 10 | int max = x; 11 | int square; 12 | 13 | if (x <= 1) { 14 | return x; 15 | } 16 | 17 | while (min <= max) { 18 | result = (min + max) / 2; 19 | square = result * result; 20 | 21 | if (is_overflow(square, result, result)) { 22 | max = result - 1; 23 | continue; 24 | } 25 | 26 | if (square == x) { 27 | return result; 28 | } 29 | else if (square < x) { 30 | min = result + 1; 31 | } 32 | else { 33 | max = result - 1; 34 | } 35 | } 36 | 37 | return (square < x) ? result : (result - 1); 38 | } 39 | }; -------------------------------------------------------------------------------- /string_to_integer_atoi.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int atoi(const char *str) { 4 | bool minus = false; // 不确定的情况下先假设为正数 5 | 6 | while (' ' == *str) { 7 | // 先消除头上连续的空格 8 | ++str; 9 | } 10 | 11 | // 判断正负数 12 | if (('+' == *str) || ('-' == *str)) { 13 | if ('-' == *str) { 14 | minus = true; 15 | } 16 | 17 | ++str; 18 | } 19 | 20 | // 有非数字就返回0 21 | if (('\0' == *str) || (*str < '0') || (*str > '9')) { 22 | return 0; 23 | } 24 | 25 | unsigned long long ull = 0; // 小心溢出,我们这里处理32位数。 26 | 27 | while (*str != '\0') { 28 | // 遇到非数字就中止 29 | if ((*str < '0') || (*str > '9')) { 30 | break; 31 | } 32 | 33 | ull = ull * 10 + (*str - '0'); 34 | 35 | if (minus) { 36 | if (ull > 0x80000000) { 37 | // 负数溢出 38 | return INT_MIN; 39 | } 40 | } 41 | else { 42 | if (ull > 0x7fffffff) { 43 | // 正数溢出 44 | return INT_MAX; 45 | } 46 | } 47 | 48 | ++str; 49 | } 50 | 51 | return minus ? -1 * (int)ull : (int)ull; 52 | } 53 | }; -------------------------------------------------------------------------------- /subsets.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void generate_subsets(vector &set, 4 | int index, 5 | vector &subset, 6 | vector > &result) { 7 | for (int i = index; i < set.size(); ++i) { 8 | subset.push_back(set[i]); 9 | result.push_back(subset); 10 | 11 | if (i < (set.size() - 1)) { 12 | generate_subsets(set, i + 1, subset, result); 13 | } 14 | 15 | subset.pop_back(); 16 | } 17 | } 18 | 19 | vector > subsets(vector &S) { 20 | vector > result; 21 | vector subset; 22 | 23 | if (0 == S.size()) { 24 | return result; 25 | } 26 | 27 | sort(S.begin(), S.end()); 28 | // 空集一定是个子集 29 | result.push_back(subset); 30 | 31 | generate_subsets(S, 0, subset, result); 32 | 33 | return result; 34 | } 35 | }; -------------------------------------------------------------------------------- /subsets_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void generate_subsets(vector &set, 4 | int index, 5 | vector &subset, 6 | vector > &subsets) { 7 | int size = set.size(); 8 | 9 | for (int i = index; i < size; ) { 10 | subset.push_back(set[i]); 11 | subsets.push_back(subset); 12 | 13 | if ((i + 1) < size) { 14 | generate_subsets(set, i + 1, subset, subsets); 15 | } 16 | 17 | subset.pop_back(); 18 | 19 | int j = i + 1; 20 | 21 | while ((j < size) && (set[i] == set[j])) { 22 | ++j; 23 | } 24 | 25 | i = j; 26 | } 27 | } 28 | 29 | vector > subsetsWithDup(vector &S) { 30 | vector > subsets; 31 | vector subset; 32 | 33 | if (0 == S.size()) { 34 | return subsets; 35 | } 36 | 37 | sort(S.begin(), S.end()); 38 | // 空集一定是个子集 39 | subsets.push_back(subset); 40 | 41 | generate_subsets(S, 0, subset, subsets); 42 | 43 | return subsets; 44 | } 45 | }; -------------------------------------------------------------------------------- /substring_with_concatenation_of_all_words.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector findSubstring(string S, vector &L) { 4 | vector results; 5 | int l_size = L.size(); 6 | 7 | 8 | if (l_size <= 0) { 9 | return results; 10 | } 11 | 12 | map count_of_word_for_l; 13 | map count_of_word_for_s; 14 | int word_len = L[0].length(); 15 | int i; 16 | int j; 17 | 18 | for (i = 0; i < l_size; ++i) { 19 | ++count_of_word_for_l[L[i]]; // 统计L里每个单词出现的次数 20 | } 21 | 22 | for (i = 0; i <= (int)S.length() - (word_len * l_size); ++i) { 23 | count_of_word_for_s.clear(); 24 | 25 | for (j = 0; j < l_size; ++j) { 26 | string word = S.substr(i + j * word_len, word_len); 27 | 28 | if (count_of_word_for_l.find(word) != count_of_word_for_l.end()) { 29 | ++count_of_word_for_s[word]; 30 | 31 | if (count_of_word_for_s[word] > count_of_word_for_l[word]) { 32 | break; 33 | } 34 | } 35 | else { 36 | break; 37 | } 38 | } 39 | 40 | if (j == l_size) { 41 | results.push_back(i); 42 | } 43 | } 44 | 45 | return results; 46 | } 47 | }; -------------------------------------------------------------------------------- /sudoku_solver.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_valid_sudoku(vector > &board, int x, int y) { 4 | int row; 5 | int col; 6 | 7 | // Check columns on each row 8 | for (row = 0; row < 9; ++row) { 9 | if ((x != row) && (board[row][y] == board[x][y])) { 10 | return false; 11 | } 12 | } 13 | 14 | // Check rows on each column 15 | for (col = 0; col < 9; ++col) { 16 | if ((y != col) && (board[x][col] == board[x][y])) { 17 | return false; 18 | } 19 | } 20 | 21 | // Check block 22 | for (row = (x / 3) * 3; row < (x / 3 + 1) * 3; ++row) { 23 | for (col = (y / 3) * 3; col < (y / 3 + 1) * 3; ++col) { 24 | if ((x != row) && (y != col) && (board[row][col] == board[x][y])) { 25 | return false; 26 | } 27 | } 28 | } 29 | 30 | return true; 31 | } 32 | 33 | bool solve_sudoku(vector > &board) { 34 | for (int row = 0; row < 9; ++row) { 35 | for (int col = 0; col < 9; ++col) { 36 | if ('.' == board[row][col]) { 37 | for (int i = 1; i <= 9; ++i) { 38 | board[row][col] = '0' + i; 39 | 40 | if (is_valid_sudoku(board, row, col)) { 41 | if (solve_sudoku(board)) { 42 | return true; 43 | } 44 | } 45 | 46 | board[row][col] = '.'; 47 | } 48 | 49 | return false; 50 | } 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | void solveSudoku(vector > &board) { 58 | solve_sudoku(board); 59 | } 60 | }; -------------------------------------------------------------------------------- /sum_root_to_leaf_numbers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void sum_of_numbers(TreeNode *root, int &sum) { 4 | if (root != NULL) { 5 | if ((NULL == root->left) && (NULL == root->right)) { 6 | sum += root->val; 7 | } 8 | else { 9 | if (root->left != NULL) { 10 | root->left->val += root->val * 10; 11 | sum_of_numbers(root->left, sum); 12 | } 13 | 14 | if (root->right != NULL) { 15 | root->right->val += root->val * 10; 16 | sum_of_numbers(root->right, sum); 17 | } 18 | } 19 | } 20 | } 21 | 22 | int sumNumbers(TreeNode *root) { 23 | int sum = 0; 24 | 25 | sum_of_numbers(root, sum); 26 | 27 | return sum; 28 | } 29 | }; -------------------------------------------------------------------------------- /surrounded_regions.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void mark(vector > &board, queue > &queue_of_o) { 4 | while (!queue_of_o.empty()) { 5 | pair point = queue_of_o.front(); 6 | int row = point.first; 7 | int col = point.second; 8 | int height = board.size(); 9 | int width = board[0].size(); 10 | 11 | queue_of_o.pop(); 12 | 13 | if (((row >= 0) && (row < height)) && 14 | ((col >= 0) && (col < width)) && 15 | ('O' == board[row][col])) { 16 | board[row][col] = '#'; 17 | 18 | queue_of_o.push(pair(row - 1, col)); 19 | queue_of_o.push(pair(row + 1, col)); 20 | queue_of_o.push(pair(row, col - 1)); 21 | queue_of_o.push(pair(row, col + 1)); 22 | } 23 | } 24 | } 25 | 26 | void solve(vector > &board) { 27 | // 原来采用DFS,但是由于测试用例修改,数据变大,会因为递归导致堆栈溢出,改为BFS。 28 | int height = board.size(); 29 | 30 | if (0 == height) { 31 | return; 32 | } 33 | 34 | int width = board[0].size(); 35 | int row; 36 | int col; 37 | queue > queue_of_o; 38 | 39 | for (row = 0; row < height; ++row) { 40 | // 第一列 41 | if ('O' == board[row][0]) { 42 | queue_of_o.push(pair(row, 0)); 43 | mark(board, queue_of_o); 44 | } 45 | 46 | // 最后一列 47 | if ('O' == board[row][width - 1]) { 48 | queue_of_o.push(pair(row, width - 1)); 49 | mark(board, queue_of_o); 50 | } 51 | } 52 | 53 | for (col = 0; col < width; ++col) { 54 | // 第一行 55 | if ('O' == board[0][col]) { 56 | queue_of_o.push(pair(0, col)); 57 | mark(board, queue_of_o); 58 | } 59 | 60 | // 最后一行 61 | if ('O' == board[height - 1][col]) { 62 | queue_of_o.push(pair(height - 1, col)); 63 | mark(board, queue_of_o); 64 | } 65 | } 66 | 67 | for (row = 0; row < height; ++row) { 68 | for (col = 0; col < width; ++col) { 69 | if ('O' == board[row][col]) { 70 | board[row][col] = 'X'; 71 | } 72 | 73 | if ('#' == board[row][col]) { 74 | board[row][col] = 'O'; 75 | } 76 | } 77 | } 78 | } 79 | }; -------------------------------------------------------------------------------- /swap_nodes_in_pairs.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void insert_two_nodes(ListNode *node_1, 4 | ListNode *node_2, 5 | ListNode *&head, 6 | ListNode *&tail) { 7 | if (NULL == head) { 8 | head = node_2; 9 | tail = node_2; 10 | } 11 | else { 12 | if (node_2 != NULL) { 13 | tail->next = node_2; 14 | tail = node_2; 15 | } 16 | } 17 | 18 | if (NULL == head) { 19 | head = node_1; 20 | tail = node_1; 21 | } 22 | else { 23 | tail->next = node_1; 24 | tail = node_1; 25 | } 26 | } 27 | 28 | ListNode *swapPairs(ListNode *head) { 29 | ListNode *swapped_head = NULL; 30 | ListNode *swapped_tail = NULL; 31 | 32 | while (head != NULL) { 33 | ListNode *node_1 = head; 34 | ListNode *node_2 = node_1 ? node_1->next : NULL; 35 | 36 | head = head->next; 37 | head = head ? head->next : NULL; 38 | 39 | insert_two_nodes(node_1, node_2, swapped_head, swapped_tail); 40 | } 41 | 42 | if (NULL != swapped_tail) { 43 | swapped_tail->next = NULL; 44 | } 45 | 46 | return swapped_head; 47 | } 48 | }; -------------------------------------------------------------------------------- /symmetric_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_symmetric(TreeNode *left, TreeNode *right) { 4 | if ((NULL == left) && (NULL == right)) { 5 | return true; 6 | } 7 | else if ((NULL == left) || (NULL == right)) { 8 | return false; 9 | } 10 | else { 11 | if (left->val == right->val) { 12 | return (is_symmetric(left->left, right->right) && 13 | is_symmetric(left->right, right->left)); 14 | } 15 | else { 16 | return false; 17 | } 18 | } 19 | } 20 | bool isSymmetric(TreeNode *root) { 21 | if (NULL == root) { 22 | return true; 23 | } 24 | else { 25 | return is_symmetric(root->left, root->right); 26 | } 27 | } 28 | }; -------------------------------------------------------------------------------- /text_justification.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector fullJustify(vector &words, int L) { 4 | vector result; 5 | vector > lines; 6 | vector line; 7 | int i; 8 | int j; 9 | 10 | for (i = 0; i < words.size(); ++i) { 11 | int len = 0; 12 | 13 | for (j = 0; j < line.size(); ++j) { 14 | len += line[j].length() + 1; 15 | } 16 | 17 | if ((len + words[i].length()) > L) { 18 | lines.push_back(line); 19 | line.clear(); 20 | } 21 | 22 | line.push_back(words[i]); 23 | } 24 | 25 | if (line.size() > 0) { 26 | lines.push_back(line); 27 | } 28 | 29 | for (i = 0; i < lines.size(); ++i) { 30 | int spaces = L; 31 | int size = lines[i].size(); 32 | string str = lines[i][0]; // 初始化字符串 33 | 34 | // 计算有多少个空格 35 | for (j = 0; j < size; ++j) { 36 | spaces -= lines[i][j].length(); 37 | } 38 | 39 | for (j = 1; j < size; ++j) { 40 | if (i < (lines.size() - 1)) { 41 | int average_spaces = spaces / (size - j); 42 | int extra_spaces = spaces % (size - j); 43 | 44 | str.append(average_spaces, ' '); 45 | spaces -= average_spaces; 46 | 47 | if (extra_spaces > 0) { 48 | str.append(" "); 49 | spaces -= 1; 50 | } 51 | } 52 | else { 53 | // 最后一行特别处理 54 | if (j < size) { 55 | str.append(" "); 56 | spaces -= 1; 57 | } 58 | else { 59 | str.append(spaces, ' '); 60 | spaces = 0; 61 | } 62 | } 63 | 64 | str += lines[i][j]; 65 | } 66 | 67 | if (spaces > 0) { 68 | str.append(spaces, ' '); 69 | } 70 | 71 | result.push_back(str); 72 | } 73 | 74 | return result; 75 | } 76 | }; -------------------------------------------------------------------------------- /trapping_rain_water.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_in_range(const pair &range, const pair &sub_range) { 4 | return ((range.first <= sub_range.first) && (range.second >= sub_range.second)); 5 | } 6 | 7 | int calc_volume(int bars[], const pair &range) { 8 | int start = range.first; 9 | int end = range.second; 10 | int volume = min(bars[start], bars[end]) * (end - start - 1); 11 | 12 | // Range范围内其他柱子的高度必须小于等于min(bars[start], bars[end])。 13 | for (int i = start + 1; i < end; ++i) { 14 | volume -= bars[i]; 15 | } 16 | 17 | return volume; 18 | } 19 | 20 | int trap(int A[], int n) { 21 | stack > ranges; 22 | stack bar_positions; 23 | 24 | for (int i = 0; i < n; ++i) { 25 | if (bar_positions.empty()) { 26 | bar_positions.push(i); 27 | } 28 | else { 29 | if (A[i] < A[bar_positions.top()]) { 30 | // 比栈顶元素小,继续压入。 31 | bar_positions.push(i); 32 | } 33 | else { 34 | int start; 35 | pair range; 36 | 37 | while (!bar_positions.empty()) { 38 | start = bar_positions.top(); 39 | 40 | if (A[start] > A[i]) { 41 | break; 42 | } 43 | 44 | // 弹出所有小于等于A[i]的元素 45 | bar_positions.pop(); 46 | } 47 | 48 | // 注意,这里要分两种情况: 49 | // 1. A[start]被弹出,那么[start, i]正好构成一个区间,并且这之间的数一定小于A[start]。 50 | // 2. A[start]没有被弹出,[start, i]构成一个区间,并且有可能合并更多区间。 51 | bar_positions.push(i); 52 | range.first = start; 53 | range.second = i; 54 | 55 | while (!ranges.empty()) { 56 | // 可重叠的子区间弹出 57 | if (is_in_range(range, ranges.top())) { 58 | ranges.pop(); 59 | } 60 | else { 61 | break; 62 | } 63 | } 64 | 65 | ranges.push(range); 66 | } 67 | } 68 | } 69 | 70 | int volume = 0; 71 | 72 | while (!ranges.empty()) { 73 | volume += calc_volume(A, ranges.top()); 74 | ranges.pop(); 75 | } 76 | 77 | return volume; 78 | } 79 | }; -------------------------------------------------------------------------------- /triangle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minimumTotal(vector > &triangle) { 4 | int min_total = INT_MAX; 5 | int levels = triangle.size(); 6 | vector sums(levels); 7 | int i; 8 | int j; 9 | 10 | sums[0] = triangle[0][0]; 11 | 12 | for (i = 1; i < levels; ++i) { 13 | sums[i] = sums[i - 1] + triangle[i][i]; 14 | 15 | for (j = i - 1; j > 0; --j) { 16 | sums[j] = min(sums[j - 1], sums[j]) + triangle[i][j]; 17 | } 18 | 19 | sums[0] += triangle[i][0]; 20 | } 21 | 22 | for (i = 0; i < levels; ++i) { 23 | if (sums[i] < min_total) { 24 | min_total = sums[i]; 25 | } 26 | } 27 | 28 | return min_total; 29 | } 30 | }; -------------------------------------------------------------------------------- /two_sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector &numbers, int target) { 4 | vector result; 5 | map > indexes; 6 | int i, j, count = numbers.size(); 7 | 8 | for (i = 0; i < count; ++i) { 9 | indexes[numbers[i]].push_back(i + 1); 10 | } 11 | 12 | sort(numbers.begin(), numbers.end()); 13 | i = 0; 14 | j = count - 1; 15 | 16 | while (i < j) { 17 | int left_value = numbers[i], right_value = numbers[j]; 18 | 19 | if ((left_value + right_value) < target) { 20 | ++i; 21 | } 22 | else if ((left_value + right_value) > target) { 23 | --j; 24 | } 25 | else { 26 | vector::iterator left_it = indexes[left_value].begin(); 27 | vector::iterator right_it = indexes[right_value].begin(); 28 | 29 | if (left_it == right_it) { 30 | ++right_it; 31 | } 32 | 33 | result.push_back((*left_it < *right_it) ? *left_it : *right_it); 34 | result.push_back((*left_it < *right_it) ? *right_it : *left_it); 35 | 36 | break; 37 | } 38 | } 39 | 40 | return result; 41 | } 42 | }; -------------------------------------------------------------------------------- /unique_binary_search_trees.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int num_trees(int n, vector &nums) { 4 | if (nums[n] > 0) { 5 | return nums[n]; 6 | } 7 | 8 | if (n <= 1) { 9 | nums[n] = 1; 10 | } 11 | else { 12 | int num = 0; 13 | 14 | for (int i = 0; i < n; ++i) { 15 | num += (num_trees(i, nums) * num_trees(n - i - 1, nums)); 16 | } 17 | 18 | nums[n] = num; 19 | } 20 | 21 | return nums[n]; 22 | } 23 | 24 | int numTrees(int n) { 25 | vector nums(n + 1, 0); 26 | 27 | nums[0] = 1; 28 | 29 | return num_trees(n, nums); 30 | } 31 | }; -------------------------------------------------------------------------------- /unique_binary_search_trees_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void generate_trees(int start, 4 | int end, 5 | vector &trees) { 6 | if (start > end) { 7 | trees.push_back(NULL); 8 | } 9 | else { 10 | int i; 11 | int j; 12 | int k; 13 | 14 | for (i = start; i <= end; ++i) { 15 | vector left_sub_trees; 16 | vector right_sub_trees; 17 | 18 | generate_trees(start, i - 1, left_sub_trees); 19 | generate_trees(i + 1, end, right_sub_trees); 20 | 21 | for (j = 0; j < left_sub_trees.size(); ++j) { 22 | for (k = 0; k < right_sub_trees.size(); ++k) { 23 | TreeNode *node = new TreeNode(i); 24 | 25 | node->left = left_sub_trees[j]; 26 | node->right = right_sub_trees[k]; 27 | trees.push_back(node); 28 | } 29 | } 30 | } 31 | } 32 | } 33 | 34 | vector generateTrees(int n) { 35 | vector trees; 36 | 37 | generate_trees(1, n, trees); 38 | 39 | return trees; 40 | } 41 | }; -------------------------------------------------------------------------------- /unique_paths.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int unique_paths(int x, int y, vector > &paths) { 4 | if (0 == paths[x][y]) { 5 | if ((x - 1) >= 0) { 6 | paths[x][y] += unique_paths(x - 1, y, paths); 7 | } 8 | 9 | if ((y - 1) >= 0) { 10 | paths[x][y] += unique_paths(x, y - 1, paths); 11 | } 12 | } 13 | 14 | return paths[x][y]; 15 | } 16 | int uniquePaths(int m, int n) { 17 | vector > paths(m, vector(n, 0)); 18 | 19 | paths[0][0] = 1; 20 | 21 | return unique_paths(m - 1, n - 1, paths); 22 | } 23 | }; -------------------------------------------------------------------------------- /unique_paths_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int unique_paths_with_obstacles(const vector > &grid, 4 | int row, 5 | int col, 6 | vector > &paths) { 7 | if (0 == paths[row][col]) { 8 | if (0 == grid[row][col]) { 9 | if ((row - 1) >= 0) { 10 | paths[row][col] = unique_paths_with_obstacles(grid, 11 | row - 1, 12 | col, 13 | paths); 14 | } 15 | 16 | if ((col - 1) >= 0) { 17 | paths[row][col] += unique_paths_with_obstacles(grid, 18 | row, 19 | col - 1, 20 | paths); 21 | } 22 | } 23 | } 24 | 25 | return paths[row][col]; 26 | } 27 | 28 | int uniquePathsWithObstacles(vector > &obstacleGrid) { 29 | int rows = obstacleGrid.size(); 30 | int cols = obstacleGrid[0].size(); 31 | vector > paths(rows, vector(cols, 0)); 32 | 33 | paths[0][0] = (0 == obstacleGrid[0][0]) ? 1 : 0; 34 | 35 | return unique_paths_with_obstacles(obstacleGrid, 36 | rows - 1, 37 | cols - 1, 38 | paths); 39 | } 40 | }; -------------------------------------------------------------------------------- /valid_number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isNumber(const char *s) { 4 | // 条件比较复杂,但实际就是个状态机。 5 | const int INIT = 0; 6 | const int INT = 10; // 整数 7 | const int SYMBOL = 20; // 正负号 8 | const int SINGLE_POINT = 30; // 单个小数点 9 | const int FLOAT = 40; // 浮点数 10 | const int EXP = 50; // e 11 | const int EXP_INT = 60; // e的整数次方 12 | const int EXP_SYMBOL = 70; // e+/e-,等待后续内容 13 | const int ENDING_SPACES = 80; 14 | int state = INIT; 15 | 16 | while (*s != '\0') { 17 | char c = *s; 18 | 19 | switch (state) { 20 | case INIT: 21 | if ((c >= '0') && (c <= '9')) { 22 | state = INT; 23 | } 24 | else if (('+' == c) || ('-' == c)) { 25 | state = SYMBOL; 26 | } 27 | else if ('.' == c) { 28 | state = SINGLE_POINT; 29 | } 30 | else if (' ' != c) { 31 | return false; 32 | } 33 | 34 | break; 35 | case INT: 36 | if ((c < '0') || ( c > '9')) { 37 | if ('.' == c) { 38 | state = FLOAT; 39 | } 40 | else if ('e' == c) { 41 | state = EXP; 42 | } 43 | else if (' ' == c) { 44 | state = ENDING_SPACES; 45 | } 46 | else { 47 | return false; 48 | } 49 | } 50 | 51 | break; 52 | case SYMBOL: 53 | if ((c >= '0') && (c <= '9')) { 54 | state = INT; 55 | } 56 | else if ('.' == c) { 57 | state = SINGLE_POINT; 58 | } 59 | else { 60 | return false; 61 | } 62 | 63 | break; 64 | case SINGLE_POINT: 65 | if ((c >= '0') && (c <= '9')) { 66 | state = FLOAT; 67 | } 68 | else { 69 | return false; 70 | } 71 | 72 | break; 73 | case FLOAT: 74 | if ((c < '0') || (c > '9')) { 75 | if ('e' == c) { 76 | state = EXP; 77 | } 78 | else if (' ' == c) { 79 | state = ENDING_SPACES; 80 | } 81 | else { 82 | return false; 83 | } 84 | } 85 | 86 | break; 87 | case EXP: 88 | if ((c >= '0') && (c <= '9')) { 89 | state = EXP_INT; 90 | } 91 | else if (('+' == c) || ('-' == c)) { 92 | state = EXP_SYMBOL; 93 | } 94 | else { 95 | return false; 96 | } 97 | 98 | break; 99 | case EXP_INT: 100 | if ((c < '0') || (c > '9')) { 101 | if (' ' == c) { 102 | state = ENDING_SPACES; 103 | } 104 | else { 105 | return false; 106 | } 107 | } 108 | 109 | break; 110 | case EXP_SYMBOL: 111 | if ((c >= '0') && (c <= '9')) { 112 | state = EXP_INT; 113 | } 114 | else { 115 | return false; 116 | } 117 | 118 | break; 119 | case ENDING_SPACES: 120 | if (c != ' ') { 121 | return false; 122 | } 123 | 124 | break; 125 | } 126 | 127 | ++s; 128 | } 129 | 130 | return (INT == state) || \ 131 | (FLOAT == state) || \ 132 | (EXP_INT == state) || \ 133 | (ENDING_SPACES == state); 134 | } 135 | }; -------------------------------------------------------------------------------- /valid_palindrome.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void to_low(string &s) { 4 | for (int i = 0; i < s.length(); ++i) { 5 | if ((s[i] >= 'A') && (s[i] <= 'Z')) { 6 | s[i] += 'a' - 'A'; 7 | } 8 | } 9 | } 10 | 11 | bool is_alphanumeric(char c) { 12 | return (((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))); 13 | } 14 | 15 | bool isPalindrome(string s) { 16 | int i = 0; 17 | int j = s.length() - 1; 18 | 19 | to_low(s); 20 | 21 | while (i < j) { 22 | if (!is_alphanumeric(s[i])) { 23 | ++i; 24 | continue; 25 | } 26 | else if (!is_alphanumeric(s[j])) { 27 | --j; 28 | continue; 29 | } 30 | else { 31 | if (s[i] != s[j]) { 32 | return false; 33 | } 34 | else { 35 | ++i; 36 | --j; 37 | } 38 | } 39 | } 40 | 41 | return true; 42 | } 43 | }; -------------------------------------------------------------------------------- /valid_parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValid(string s) { 4 | stack left_pars; 5 | const char *str = s.c_str(); 6 | 7 | while (*str != '\0') { 8 | char c = *str; 9 | 10 | if (('(' == c) || ('[' == c) || ('{' == c)) { 11 | left_pars.push(c); 12 | } 13 | else { 14 | if (left_pars.empty()) { 15 | return false; 16 | } 17 | 18 | char expected; 19 | 20 | switch (c) { 21 | case ')': 22 | expected = '('; 23 | break; 24 | case ']': 25 | expected = '['; 26 | break; 27 | case '}': 28 | expected = '{'; 29 | break; 30 | } 31 | 32 | if (left_pars.top() == expected) { 33 | left_pars.pop(); 34 | } 35 | else { 36 | return false; 37 | } 38 | } 39 | 40 | ++str; 41 | } 42 | 43 | return left_pars.empty(); 44 | } 45 | }; -------------------------------------------------------------------------------- /valid_sudoku.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValidSudoku(vector > &board) { 4 | vector marks; 5 | int row; 6 | int col; 7 | int block; 8 | int index; 9 | 10 | // Check by row 11 | for (row = 0; row < 9; ++row) { 12 | marks.assign(9, 0); 13 | 14 | for (col = 0; col < 9; ++col) { 15 | if ('.' == board[row][col]) { 16 | continue; 17 | } 18 | 19 | index = board[row][col] - '1'; 20 | ++marks[index]; 21 | 22 | if (marks[index] > 1) { 23 | return false; 24 | } 25 | } 26 | } 27 | 28 | // Checl by column 29 | for (col = 0; col < 9; ++col) { 30 | marks.assign(9, 0); 31 | 32 | for (row = 0; row < 9; ++row) { 33 | if ('.' == board[row][col]) { 34 | continue; 35 | } 36 | 37 | index = board[row][col] - '1'; 38 | ++marks[index]; 39 | 40 | if (marks[index] > 1) { 41 | return false; 42 | } 43 | } 44 | } 45 | 46 | // Check by block 47 | for (block = 0; block < 9; ++block) { 48 | marks.assign(9, 0); 49 | 50 | for (row = (block / 3) * 3; row < (block / 3) * 3 + 3; ++row) { 51 | for (col = (block % 3) * 3; col < (block % 3) * 3 + 3; ++col) { 52 | if ('.' == board[row][col]) { 53 | continue; 54 | } 55 | 56 | index = board[row][col] - '1'; 57 | ++marks[index]; 58 | 59 | if (marks[index] > 1) { 60 | return false; 61 | } 62 | } 63 | } 64 | } 65 | return true; 66 | } 67 | }; -------------------------------------------------------------------------------- /validate_binary_search_tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool is_valid_bst(TreeNode *root, int min, int max) { 4 | if (NULL == root) { 5 | return true; 6 | } 7 | 8 | if ((root->val >= min) && (root->val <= max)) { 9 | return (is_valid_bst(root->left, min, root->val - 1) && 10 | is_valid_bst(root->right, root->val + 1, max)); 11 | } 12 | else { 13 | return false; 14 | } 15 | } 16 | 17 | bool isValidBST(TreeNode *root) { 18 | return is_valid_bst(root, INT_MIN, INT_MAX); 19 | } 20 | }; -------------------------------------------------------------------------------- /wildcard_matching.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isMatch(const char *s, const char *p) { 4 | bool star = false; // *有没有出现过 5 | const char *saved_s = NULL; 6 | const char *saved_p = NULL; 7 | 8 | while (*s != '\0') { 9 | if (*p != '*') { 10 | if ((*s == *p) || ('?' == *p)) { 11 | ++s; 12 | ++p; 13 | } 14 | else { 15 | if (star) { 16 | // p固定在*之后的字符串,s则不断增长试图匹配。 17 | s = ++saved_s; 18 | p = saved_p + 1; 19 | } 20 | else { 21 | return false; 22 | } 23 | } 24 | } 25 | else { 26 | star = true; 27 | 28 | while ('*' == *p) { 29 | ++p; 30 | } 31 | 32 | saved_s = s; 33 | // 记录连续出现的最后一个*的位置 34 | saved_p = p - 1; 35 | } 36 | } 37 | 38 | // 处理p尾部的* 39 | while ('*' == *p) { 40 | ++p; 41 | } 42 | 43 | return (('\0' == *s) && ('\0' == *p)); 44 | } 45 | }; -------------------------------------------------------------------------------- /word_break.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool wordBreak(string s, unordered_set &dict) { 4 | int len = s.length(); 5 | vector match(len + 1, false); 6 | 7 | match[0] = true; 8 | 9 | for (int i = 1; i <= len; ++i) { 10 | for (int j = i - 1; j >= 0; --j) { 11 | if (match[j]) { 12 | if (dict.find(s.substr(j, i - j)) != dict.end()) { 13 | match[i] = true; // 前i个字母可以match 14 | break; 15 | } 16 | } 17 | } 18 | } 19 | 20 | return match[len]; 21 | } 22 | }; -------------------------------------------------------------------------------- /word_break_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector wordBreak(string s, unordered_set &dict) { 4 | vector result; 5 | vector path; 6 | int len = s.length(); 7 | vector match(len + 1, false); 8 | vector > lookup(len + 1); 9 | 10 | match[0] = true; 11 | 12 | for (int i = 1; i <= len; ++i) { 13 | for (int prev = 0; prev < i; ++prev) { 14 | if (match[prev] && (dict.find(s.substr(prev, i - prev)) != dict.end())) { 15 | // 找到一个匹配的单词 16 | match[i] = true; 17 | lookup[i].push_back(prev); 18 | } 19 | } 20 | } 21 | 22 | if (!match[len]) { 23 | return result; 24 | } 25 | 26 | back_trace(s, len, lookup, path, result); 27 | } 28 | 29 | protected: 30 | void back_trace(string &s, 31 | int index, 32 | vector > &lookup, 33 | vector &path, 34 | vector &result) { 35 | if (0 == index) { 36 | string str; 37 | int size = path.size(); 38 | 39 | for (int i = size - 1; i >= 0; --i) { 40 | str.append(path[i]); 41 | 42 | if (i != 0) { 43 | str.append(" "); 44 | } 45 | } 46 | 47 | result.push_back(str); 48 | } 49 | else { 50 | for (list::iterator it = lookup[index].begin(); 51 | it != lookup[index].end(); 52 | ++it) { 53 | int prev = *it; 54 | 55 | path.push_back(s.substr(prev, index - prev)); 56 | back_trace(s, prev, lookup, path, result); 57 | path.pop_back(); 58 | } 59 | } 60 | } 61 | }; -------------------------------------------------------------------------------- /word_ladder.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | // 广度优先搜索 4 | int ladderLength(string start, string end, unordered_set &dict) { 5 | int len = 1; 6 | int curr = 0; 7 | int next = 1; 8 | queue queues[2]; 9 | 10 | queues[curr].push(start); 11 | 12 | while (!queues[curr].empty()) { 13 | while (!queues[curr].empty()) { 14 | string str(queues[curr].front()); 15 | 16 | queues[curr].pop(); 17 | 18 | for (int i = 0; i < str.size(); ++i) { 19 | for (char c = 'a'; c <= 'z'; ++c) { 20 | if (c == str[i]) { 21 | continue; 22 | } 23 | 24 | char tmp = str[i]; 25 | 26 | str[i] = c; 27 | 28 | if (str == end) { 29 | return len + 1; 30 | } 31 | else { 32 | if (dict.count(str) > 0) { 33 | queues[next].push(str); 34 | dict.erase(str); 35 | } 36 | } 37 | 38 | str[i] = tmp; 39 | } 40 | } 41 | } 42 | 43 | swap(curr, next); 44 | ++len; 45 | } 46 | 47 | return 0; 48 | } 49 | }; -------------------------------------------------------------------------------- /word_ladder_ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | protected: 3 | void build_ladder(unordered_map > &traces, 4 | const string &word, 5 | vector &ladder, 6 | vector > &ladders) { 7 | if (0 == traces[word].size()) { 8 | ladder.push_back(word); 9 | 10 | vector tmp = ladder; 11 | 12 | reverse(tmp.begin(), tmp.end()); 13 | ladders.push_back(tmp); 14 | 15 | ladder.pop_back(); 16 | } 17 | else { 18 | ladder.push_back(word); 19 | 20 | for (vector::iterator it = traces[word].begin(); 21 | it != traces[word].end(); ++it) { 22 | build_ladder(traces, *it, ladder, ladders); 23 | } 24 | 25 | ladder.pop_back(); 26 | } 27 | } 28 | 29 | public: 30 | // 分层BFS遍历,同时记录前缀,当某一层出现end时结束,生成ladder。 31 | vector > findLadders(string start, string end, unordered_set &dict) { 32 | vector > ladders; 33 | unordered_map > traces; 34 | unordered_set levels[2]; 35 | int curr = 0; 36 | int prev = 1; 37 | 38 | for (unordered_set::iterator it = dict.begin(); 39 | it != dict.end(); 40 | ++it) { 41 | traces[*it] = vector(); 42 | } 43 | 44 | levels[curr].insert(start); 45 | 46 | while (true) { 47 | swap(curr, prev); 48 | 49 | for (unordered_set::iterator it = levels[prev].begin(); 50 | it != levels[prev].end(); 51 | ++it) { 52 | dict.erase(*it); 53 | } 54 | 55 | levels[curr].clear(); 56 | 57 | for (unordered_set::iterator it = levels[prev].begin(); 58 | it != levels[prev].end(); 59 | ++it) { 60 | for (size_t pos = 0; pos < it->size(); ++pos) { 61 | string word = *it; 62 | 63 | for (char c = 'a'; c <= 'z'; ++c) { 64 | if (word[pos] == c) { 65 | continue; 66 | } 67 | 68 | word[pos] = c; 69 | 70 | if ((dict.count(word) > 0) || (word == end)) { 71 | traces[word].push_back(*it); 72 | levels[curr].insert(word); 73 | } 74 | } 75 | } 76 | } 77 | 78 | if (0 == levels[curr].size()) { 79 | return ladders; 80 | } 81 | 82 | if (levels[curr].count(end) > 0) { 83 | break; 84 | } 85 | } 86 | 87 | vector ladder; 88 | 89 | build_ladder(traces, end, ladder, ladders); 90 | 91 | return ladders; 92 | } 93 | }; -------------------------------------------------------------------------------- /word_search.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool search_word(vector > &board, 4 | int row, 5 | int col, 6 | const char *word, 7 | vector > &visit_statuses) { 8 | if ('\0' == *word) { 9 | return true; 10 | } 11 | 12 | int height = board.size(); 13 | int width = board[0].size(); 14 | int prev_row = row - 1; 15 | int next_row = row + 1; 16 | int prev_col = col - 1; 17 | int next_col = col + 1; 18 | 19 | // 向上探索 20 | if (prev_row >= 0) { 21 | if ((!visit_statuses[prev_row][col]) && (board[prev_row][col] == *word)) { 22 | visit_statuses[prev_row][col] = true; 23 | 24 | if (search_word(board, prev_row, col, word + 1, visit_statuses)) { 25 | return true; 26 | } 27 | 28 | visit_statuses[prev_row][col] = false; 29 | } 30 | } 31 | 32 | // 向下探索 33 | if (next_row < height) { 34 | if ((!visit_statuses[next_row][col]) && (board[next_row][col] == *word)) { 35 | visit_statuses[next_row][col] = true; 36 | 37 | if (search_word(board, next_row, col, word + 1, visit_statuses)) { 38 | return true; 39 | } 40 | 41 | visit_statuses[next_row][col] = false; 42 | } 43 | } 44 | 45 | // 向左探索 46 | if (prev_col >= 0) { 47 | if ((!visit_statuses[row][prev_col]) && (board[row][prev_col] == *word)) { 48 | visit_statuses[row][prev_col] = true; 49 | 50 | if (search_word(board, row, prev_col, word + 1, visit_statuses)) { 51 | return true; 52 | } 53 | 54 | visit_statuses[row][prev_col] = false; 55 | } 56 | } 57 | 58 | // 向右探索 59 | if (next_col < width) { 60 | if ((!visit_statuses[row][next_col]) && (board[row][next_col] == *word)) { 61 | visit_statuses[row][next_col] = true; 62 | 63 | if (search_word(board, row, next_col, word + 1, visit_statuses)) { 64 | return true; 65 | } 66 | 67 | visit_statuses[row][next_col] = false; 68 | } 69 | } 70 | 71 | return false; 72 | } 73 | 74 | bool exist(vector > &board, string word) { 75 | if (0 == board.size()) { 76 | return false; 77 | } 78 | 79 | int height = board.size(); 80 | int width = board[0].size(); 81 | vector > visit_statuses(height, vector(width, false)); 82 | 83 | for (int row = 0; row < height; ++row) { 84 | for (int col = 0; col < width; ++col) { 85 | if (board[row][col] == word[0]) { 86 | visit_statuses[row][col] = true; 87 | 88 | if (search_word(board, row, col, word.c_str() + 1, visit_statuses)) { 89 | return true; 90 | } 91 | 92 | visit_statuses[row][col] = false; 93 | } 94 | } 95 | } 96 | 97 | return false; 98 | } 99 | }; -------------------------------------------------------------------------------- /zigzag_conversion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string convert(string s, int nRows) { 4 | if (1 == nRows) { 5 | return s; 6 | } 7 | 8 | string result_str; 9 | vector rows(nRows); 10 | int row = 0; 11 | int i = 0; 12 | bool down = true; // 控制方向 13 | 14 | while (i < s.length()) { 15 | rows[row].push_back(s[i]); 16 | ++i; 17 | 18 | if (0 == row) { 19 | down = true; 20 | } 21 | else if ((nRows - 1) == row) { 22 | down = false; 23 | } 24 | 25 | if (down) { 26 | ++row; 27 | } 28 | else { 29 | --row; 30 | } 31 | } 32 | 33 | for (row = 0; row < nRows; ++row) { 34 | result_str += rows[row]; 35 | } 36 | 37 | return result_str; 38 | } 39 | }; -------------------------------------------------------------------------------- /命名规范.txt: -------------------------------------------------------------------------------- 1 | 参考Google的C++编码规范。特别是以下几条: 2 | 1. 定义函数时,参数顺序为:输入参数在前,输出参数在后。 3 | 2. 局部变量初始化时声明,比如"int i = foo();"。 4 | 3. 声明次序:public->protected->private;成员函数->成员变量。对于每一块,声明次序如下: 5 | 1) typedefs和enums 6 | 2) 常量 7 | 3) 构造函数 8 | 4) 析构函数 9 | 5) 成员函数,含静态成员函数。 10 | 6) 数据成员,含静态数据成员。 11 | 12 | 其他规则: 13 | 1. 变量和函数命名全为小写,用'_'做分隔符。 14 | 1) 动词_名词 15 | 2) 名词_of_名词 16 | 3) 定语_主语 17 | 4) 名词_数字(表示第n个元素) 18 | 2. 表示个数用count,长度用len,表示大小用size。单个函数内命名统一。 19 | 3. 表示字符串用str --------------------------------------------------------------------------------