3个嵌套循环的时间复杂度计算
Time complexity calculation for 3 nested loops
我正在努力提高我的算法技能。我有一个非常简单的代码。
问题:找到所有等于 0 的三元组(不重复)。
我认为无论嵌套循环(n^3)如何,时间复杂度都是O(nlogn)。
我的理由是:
让我们说
nums
length = 3. 然后代码运行 1 次。 {-1,0,-1}
。
nums
length = 3. 然后代码运行 1 次。 {-1,0,1,2}
然后代码运行 3 次。 -1,0,1
, 01,0,2
, -1,1,2
.
同样,当长度为 5
时,代码运行 6 次[] [] [] [] [] []
,长度为 7 时,代码运行 9 次。
所以似乎被考虑的三胞胎数量增加了 3(n-2)
,其中 3<=n
。因此,时间复杂度是 n
因为 3n-6
~ n
.
但是因为我有 Arrays.sort
时间复杂度变为 O(nlogn)
。
我忽略了什么?
int[] nums = { -1, 0, 1, 2, -1, -4};
List<List<Integer>> test = new ArrayList<List<Integer>>();
nums = new int[] { -1, 0, 1};
Arrays.sort(nums);
HashSet<String> duplicates = new HashSet<String> ();
for (int i = 0 ; i < nums.length - 2 ; i++) { //i->0 - 3
for (int j = i + 1; j < nums.length - 1; j++) { // j -> 1-4
for (int k = j + 1; k < nums.length; k++) { //k ->2-5
String sInt = nums[i] + "" + nums[j] + "" + nums[k];
if ((nums[i] + nums[j] + nums[k]) == 0 && !duplicates.contains(sInt)) {
ArrayList<Integer> t = new ArrayList<Integer> ();
t.add(nums[i]);
t.add(nums[j]);
t.add(nums[k]);
test.add(t);
}
duplicates.add(sInt);
}
}
}
return test;
有 n*(n-1)(n-2)/6
个三元组,代码检查 每个 个。时间复杂度为O(n^3)
。我不明白 Arrays.sort()
在这里有什么意义。
看来你正在解决 3Sum problem of LeetCode (15)
你关于 N * Log N 排序的逻辑是正确的。但是,您的循环在 N ^ 3 处为 运行,如 。
最优解(N^2阶)为:
Java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) {
int lo = i + 1, hi = nums.length - 1, sum = 0 - nums[i];
while (lo < hi) {
if (nums[lo] + nums[hi] == sum) {
res.add(Arrays.asList(nums[i], nums[lo], nums[hi]));
while (lo < hi && nums[lo] == nums[lo + 1])
lo++;
while (lo < hi && nums[hi] == nums[hi - 1])
hi--;
lo++;
hi--;
} else if (nums[lo] + nums[hi] < sum) {
lo++;
} else {
hi--;
}
}
}
}
return res;
}
}
Python
class Solution:
def threeSum(self, nums):
res = []
nums.sort()
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
lo, hi = i + 1, len(nums) - 1
while lo < hi:
tsum = nums[i] + nums[lo] + nums[hi]
if tsum < 0:
lo += 1
if tsum > 0:
hi -= 1
if tsum == 0:
res.append((nums[i], nums[lo], nums[hi]))
while lo < hi and nums[lo] == nums[lo + 1]:
lo += 1
while lo < hi and nums[hi] == nums[hi - 1]:
hi -= 1
lo += 1
hi -= 1
return res
参考
You can usually find the most efficient solutions at this link
我正在努力提高我的算法技能。我有一个非常简单的代码。
问题:找到所有等于 0 的三元组(不重复)。
我认为无论嵌套循环(n^3)如何,时间复杂度都是O(nlogn)。 我的理由是: 让我们说
nums
length = 3. 然后代码运行 1 次。 {-1,0,-1}
。
nums
length = 3. 然后代码运行 1 次。 {-1,0,1,2}
然后代码运行 3 次。 -1,0,1
, 01,0,2
, -1,1,2
.
同样,当长度为 5
时,代码运行 6 次[] [] [] [] [] []
,长度为 7 时,代码运行 9 次。
所以似乎被考虑的三胞胎数量增加了 3(n-2)
,其中 3<=n
。因此,时间复杂度是 n
因为 3n-6
~ n
.
但是因为我有 Arrays.sort
时间复杂度变为 O(nlogn)
。
我忽略了什么?
int[] nums = { -1, 0, 1, 2, -1, -4};
List<List<Integer>> test = new ArrayList<List<Integer>>();
nums = new int[] { -1, 0, 1};
Arrays.sort(nums);
HashSet<String> duplicates = new HashSet<String> ();
for (int i = 0 ; i < nums.length - 2 ; i++) { //i->0 - 3
for (int j = i + 1; j < nums.length - 1; j++) { // j -> 1-4
for (int k = j + 1; k < nums.length; k++) { //k ->2-5
String sInt = nums[i] + "" + nums[j] + "" + nums[k];
if ((nums[i] + nums[j] + nums[k]) == 0 && !duplicates.contains(sInt)) {
ArrayList<Integer> t = new ArrayList<Integer> ();
t.add(nums[i]);
t.add(nums[j]);
t.add(nums[k]);
test.add(t);
}
duplicates.add(sInt);
}
}
}
return test;
有 n*(n-1)(n-2)/6
个三元组,代码检查 每个 个。时间复杂度为O(n^3)
。我不明白 Arrays.sort()
在这里有什么意义。
看来你正在解决 3Sum problem of LeetCode (15)
你关于 N * Log N 排序的逻辑是正确的。但是,您的循环在 N ^ 3 处为 运行,如
最优解(N^2阶)为:
Java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) {
int lo = i + 1, hi = nums.length - 1, sum = 0 - nums[i];
while (lo < hi) {
if (nums[lo] + nums[hi] == sum) {
res.add(Arrays.asList(nums[i], nums[lo], nums[hi]));
while (lo < hi && nums[lo] == nums[lo + 1])
lo++;
while (lo < hi && nums[hi] == nums[hi - 1])
hi--;
lo++;
hi--;
} else if (nums[lo] + nums[hi] < sum) {
lo++;
} else {
hi--;
}
}
}
}
return res;
}
}
Python
class Solution:
def threeSum(self, nums):
res = []
nums.sort()
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
lo, hi = i + 1, len(nums) - 1
while lo < hi:
tsum = nums[i] + nums[lo] + nums[hi]
if tsum < 0:
lo += 1
if tsum > 0:
hi -= 1
if tsum == 0:
res.append((nums[i], nums[lo], nums[hi]))
while lo < hi and nums[lo] == nums[lo + 1]:
lo += 1
while lo < hi and nums[hi] == nums[hi - 1]:
hi -= 1
lo += 1
hi -= 1
return res
参考
You can usually find the most efficient solutions at this link