https://leetcode-cn.com/problemset/database/
---------------------------------------------------------------------------------
Reprint, original: https://www.cnblogs.com/By-ruoyu/p/11311830.html
Recently begun to regain algorithm, LeetCode
brush title. By the way also record reports and problem-solving optimization ideas.
Topic links: 1. The sum of two numbers
The meaning of problems
Given an array of integers nums
and a target value target
, and you figure out a target value of the two integers in the array, and return to their array subscript.
You can assume that each input corresponds to only one answer. However, you can not re-use the same array element.
Example:
nums = [2, 7, 11, 15], target = 9
返回 [0, 1]
Meaning of the questions is very simple, it is to find two numbers, two numbers together equal target
. And to ensure that each set of input there will be an answer.
Problem-solving ideas
From the point of view meaning of the questions, just need to find the two numbers can be. Well first of all you can think of is to enumerate a combination of two numbers, but the number of combinations the number is very large, this idea would be to give up.
Equal to the sum of two numbers and target
, in turn, for a number nums[i]
, can be found in a number of additional array nums[j]
such nums[j] = target - nums[i]
. So we only need to be concerned about a number.
Violence Enumeration
Simple and crude, used to enumerate a heavy cycle nums[i]
, another re-used to look for nums[j]
.
Code:
public class Solution {
public int[] TwoSum(int[] nums, int target) { for(int i = 0; i < nums.Length; i ++) { int res = target - nums[i]; for(int j = 0; j < nums.Length; j ++) { if(i == j) continue; if(res == nums[j]) return new int[] {i, j}; } } return new int[] {}; } }
When execution: 904ms
memory consumption: 29.6MB
Ranked by time:超过21.29%
29 cases, took nearly one second. Since there are only auxiliary variable loop here, memory consumption will be negligible.
Consuming ranking is at the back of comparison, it also shows that there is a better solution.
Space for time
This key question is this: how to quickly find j
, violence enumeration in the worst case, the entire array will be searched until the last to find time complexity is O(n)
.
Well, here we can use the 哈希算法
map to achieve faster search efficiency. Theoretically 哈希算法
under a well-designed case can reach a constant level O(1)
of complexity.
An example: in the case of small value, the value may be used as a subscript array, and the array as the index value of the original array. which is:
For x = nums[i]
, there is hash[x] = i
. So at the expense of a lot of space can make query efficiency to achieve the ultimate constant level O(1)
.
But unfortunately, this question and no way to directly use this method, because int.MaxValue
is far beyond the scope of the array can be defined. It will complain at compile time, memory overflow.
Since the time being there is no way to reach O(1)
the point where you can consider using implements 哈希算法
(reservation here say, if the source code is not reading the feather in the index to see emulated has a clear hash marks guess) is Dictionary<TKey, TValue>
.
Code:
public class Solution
{
public int[] TwoSum(int[] nums, int target) { var dic = new Dictionary<int, List<int>>(); for(int i = 0; i < nums.Length; i ++) { int num = nums[i]; int res = target - num; if(dic.ContainsKey(res)) { return new int[] {i, dic[res][0]}; } if(!dic.ContainsKey(num)) { dic.Add(num, new List<int>(){}); } dic[num].Add(i); } return new int[] {}; } }
When execution: 468 ms
memory consumption: 30.5MB
Ranked by time:超过78.61%
The improved ranking algorithm can be described with the previous bad days to do, it has come to the front 30%
.
Just reached the top third, indicating that there may be further optimized algorithm.
Further optimize queries
Here we spent Dictionary
, but here TValue
is a list. Think about it, here we do not need to save the list, just to save a value, because just need to find a set of answers to!
Second, one can subtract the second judgment, determines whether there is not need to directly cover / new can.
Finally, you can reverse lookup, the value before check whether the lack of a nums[i]
corresponding deposit into is the difference, so you can subtract two temporary variables, incidentally optimized a little bit of space.
Code:
public class Solution
{
Dictionary<int, int> dic = new Dictionary<int, int>(); public int[] TwoSum(int[] nums, int target) { if(nums.Length == 2) return new int[] {0, 1}; dic.Clear(); for (int i = 0; i < nums.Length; i++) { if(dic.ContainsKey(nums[i])) return new int[] {dic[nums[i]], i}; dic[target - nums[i]] = i; } return new int[] { }; } }
When execution: 360 ms
memory consumption: 30MB
Ranked by time:超过98.83%
Compared to the previous gap between the improved algorithm is not very large, but is this a hundred millisecond gap, he moved up to the front 3%
.
This algorithm still areas for improvement, but if the birds now have had no idea how to further go down to the complexity of the query, there may need to implement a more efficient hashing algorithms.
Written in the last
Long time no contact algorithm, some strange, some of the ideas are blocked. If here for the next feather to further optimize some initial ideas, to be free after the experiment coupled with a problem-solving report.
-
Staging policies, use when the data reaches a certain extent a more efficient algorithm, when a small amount of data, it may be a hash takes longer, the need to experiment. The effect of the algorithm is to find more time-consuming threshold , with a threshold for policy choices.
-
Own hashing algorithm to achieve more efficient for the title.
https://leetcode-cn.com/problemset/database/
Recently begun to regain algorithm, LeetCode
brush title. By the way also record reports and problem-solving optimization ideas.
Topic links: 1. The sum of two numbers
The meaning of problems
Given an array of integers nums
and a target value target
, and you figure out a target value of the two integers in the array, and return to their array subscript.
You can assume that each input corresponds to only one answer. However, you can not re-use the same array element.
Example:
nums = [2, 7, 11, 15], target = 9
返回 [0, 1]
Meaning of the questions is very simple, it is to find two numbers, two numbers together equal target
. And to ensure that each set of input there will be an answer.
Problem-solving ideas
From the point of view meaning of the questions, just need to find the two numbers can be. Well first of all you can think of is to enumerate a combination of two numbers, but the number of combinations the number is very large, this idea would be to give up.
Equal to the sum of two numbers and target
, in turn, for a number nums[i]
, can be found in a number of additional array nums[j]
such nums[j] = target - nums[i]
. So we only need to be concerned about a number.
Violence Enumeration
Simple and crude, used to enumerate a heavy cycle nums[i]
, another re-used to look for nums[j]
.
Code:
public class Solution {
public int[] TwoSum(int[] nums, int target) { for(int i = 0; i < nums.Length; i ++) { int res = target - nums[i]; for(int j = 0; j < nums.Length; j ++) { if(i == j) continue; if(res == nums[j]) return new int[] {i, j}; } } return new int[] {}; } }
When execution: 904ms
memory consumption: 29.6MB
Ranked by time:超过21.29%
29 cases, took nearly one second. Since there are only auxiliary variable loop here, memory consumption will be negligible.
Consuming ranking is at the back of comparison, it also shows that there is a better solution.
Space for time
This key question is this: how to quickly find j
, violence enumeration in the worst case, the entire array will be searched until the last to find time complexity is O(n)
.
Well, here we can use the 哈希算法
map to achieve faster search efficiency. Theoretically 哈希算法
under a well-designed case can reach a constant level O(1)
of complexity.
An example: in the case of small value, the value may be used as a subscript array, and the array as the index value of the original array. which is:
For x = nums[i]
, there is hash[x] = i
. So at the expense of a lot of space can make query efficiency to achieve the ultimate constant level O(1)
.
But unfortunately, this question and no way to directly use this method, because int.MaxValue
is far beyond the scope of the array can be defined. It will complain at compile time, memory overflow.
Since the time being there is no way to reach O(1)
the point where you can consider using implements 哈希算法
(reservation here say, if the source code is not reading the feather in the index to see emulated has a clear hash marks guess) is Dictionary<TKey, TValue>
.
Code:
public class Solution
{
public int[] TwoSum(int[] nums, int target) { var dic = new Dictionary<int, List<int>>(); for(int i = 0; i < nums.Length; i ++) { int num = nums[i]; int res = target - num; if(dic.ContainsKey(res)) { return new int[] {i, dic[res][0]}; } if(!dic.ContainsKey(num)) { dic.Add(num, new List<int>(){}); } dic[num].Add(i); } return new int[] {}; } }
When execution: 468 ms
memory consumption: 30.5MB
Ranked by time:超过78.61%
The improved ranking algorithm can be described with the previous bad days to do, it has come to the front 30%
.
Just reached the top third, indicating that there may be further optimized algorithm.
Further optimize queries
Here we spent Dictionary
, but here TValue
is a list. Think about it, here we do not need to save the list, just to save a value, because just need to find a set of answers to!
Second, one can subtract the second judgment, determines whether there is not need to directly cover / new can.
Finally, you can reverse lookup, the value before check whether the lack of a nums[i]
corresponding deposit into is the difference, so you can subtract two temporary variables, incidentally optimized a little bit of space.
Code:
public class Solution
{
Dictionary<int, int> dic = new Dictionary<int, int>(); public int[] TwoSum(int[] nums, int target) { if(nums.Length == 2) return new int[] {0, 1}; dic.Clear(); for (int i = 0; i < nums.Length; i++) { if(dic.ContainsKey(nums[i])) return new int[] {dic[nums[i]], i}; dic[target - nums[i]] = i; } return new int[] { }; } }
When execution: 360 ms
memory consumption: 30MB
Ranked by time:超过98.83%
Compared to the previous gap between the improved algorithm is not very large, but is this a hundred millisecond gap, he moved up to the front 3%
.
This algorithm still areas for improvement, but if the birds now have had no idea how to further go down to the complexity of the query, there may need to implement a more efficient hashing algorithms.
Written in the last
Long time no contact algorithm, some strange, some of the ideas are blocked. If here for the next feather to further optimize some initial ideas, to be free after the experiment coupled with a problem-solving report.
-
Staging policies, use when the data reaches a certain extent a more efficient algorithm, when a small amount of data, it may be a hash takes longer, the need to experiment. The effect of the algorithm is to find more time-consuming threshold , with a threshold for policy choices.
-
Own hashing algorithm to achieve more efficient for the title.