Puzzle description
*Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Notice that the solution set must not contain duplicate triplets.
Example 1: Input: nums = [-1,0,1,2,-1,-4] Output: [[-1,-1,2],[-1,0,1]]
Example 2: Input: nums = [] Output: []
Example 3: Input: nums = [0] Output: []
Constraints: 0 <= nums.length <= 3000 -105 <= nums[i] <= 105*
End Of Desctiption
I am having some trouble solving this puzzle from leetcode I am running over the time limit so my code needs to be optimized.
The two locations I know can be fixed are the double loop entry and the loop to check if any of the lists match.
An extra issue that is not stopping me from passing but is something that could cause this to fail in some conditions is the check in the list to see if it contains the distance and is not equal to the first or second iteration since IndexOf will return the first index found.
As for the loop check I found a faster solution in python but I am unsure of the c# equivilent
Python code find whether a list
exists in list of list.
# Input List Initialization
Input = [[1, 1, 1, 2], [2, 3, 4], [1, 2, 3], [4, 5, 6]]
# List to be searched
list_search = [1, 1, 1, 2]
# Using in to find whether
# list exists or not
if list_search in Input:
print("True")
else:
print("False")
Here is my current code solution (TLDR: it works but is too slow)
public class Solution {
public IList<IList<int>> ThreeSum(int[] nums) {
/*total must always = 0
ideas to use a sort on each list to check if there are
multiple arrays that are the same combination of values
the last sum can be assumed and pulled via Arraylist since there can only be one answer assumed
values can be quickly ignored if there is no corrisponding 3rd value that sums to 0
ex -1,-1, do we have a value of 2 if not than we can ignore this combination
also if we do than we will want to temporarly store it than sort the list and compare to our already existing
list
Something to think about if the numbs array is sorted ahead of time can we ignore using the sort operation
in some conditions to save cpu time
If the size of the nums array is less than 3 than return a blank array
also if the size of the array = 3 we can assume the solution and return nums (maybe)
A possible way to make this faster would be to find a way to assume all possible values have been found or use a Addoku/Arrow-Sudoku method of solving and see if for example a value in the array is 9 and there are no negative values in a set of 2 that can = -9 than 9 can be instantly ignored and removed since the combination is not possible.
I dont think the index check is perfect since indexof checks for the first value but it has been passing all of my test cases so I will leave it for now but I will need to find a better way to remove I and Y elements from the index check to avoid duplicates.
*/
IList<IList<int>> mainLs = new List<IList<int>>();
if(nums.Length < 3){
return mainLs;
}
for(int i = 0; i< nums.Length; i++){
int currentVal = nums[i];
for(int y = 0; y< nums.Length; y++){
//is there an easier way to skip the matching index
if(i == y){
continue;
}else{
/*
We will sum the two elements together and check the distance
between the sum and 0. Than if we have the distance in our index and the value to sum to 0
is not the index we are on since we need to avoid duplicates than add that value to the array
*/
ArrayList tempNumls = new ArrayList(nums);
int sum = currentVal + nums[y];
int distance = Math.Abs(sum - 0);
//Math abs always produces a postive value which will work for us if the sum is negative but if the sum is positive it will return a positive value so we multiply by -1 to produce the proper result.
if(sum > 0){
distance = distance * -1;
}
//output the results found
// Console.WriteLine("distance: "+distance + " X & Y = "+ currentVal + " & " + nums[y]);
if(tempNumls.Contains(distance) && tempNumls.IndexOf(distance) != y && tempNumls.IndexOf(distance) != i){
ArrayList tempIls = new ArrayList() {currentVal, nums[y], distance};
//sorting and comparing will be the easiest way to make sure we do not have matching lists
tempIls.Sort();
var list = tempIls.Cast<int>().ToList();
bool match = false;
//best to find a better way to traverse and compare the list of list without
//needing to loop over them all
foreach (List<int> listname in mainLs)
{
if (listname.SequenceEqual(list))
{
match = true;
break;
}
}
if(!match){
mainLs.Add(list);
}
}
}
}
}
return mainLs;
}
}