[leetcode#259] 3Sum Smaller

Source: Internet
Author: User
Tags ranges

problem:

Given an array of n integers nums and a target, find the number of index triplets with i, j, k that satisfy the condition nums[i] + nums[j] + nums[k] < target .

For example, given nums = [-2, 0, 1, 3] , and target = 2.

Return 2. Because there is triplets which sums is less than 2:

[-2, 0, 1] [-2, 0, 3]

Follow up:
Could you solve it in O(n2) runtime?

General Analysis:

This problem are easy, but really tricky!  1:the Nums may still has duplicates, but we don ' t need-care about it, since the Problme ask us to "find the Number of index triplets I, J ", which means as long as the elements is different (not value), we could record it.  2:it asks us to find all combinations smaller than "target", which was not the same as "equal" Uting answer should be different. I have made following mistakes -to-figure out the solution:

Wrong solution 1:

 Public classSolution { Public intThreesumsmaller (int[] Nums,inttarget) {        if(Nums = =NULL)            Throw NewIllegalArgumentException ("Nums is null"); List<Integer> ret =NewArraylist<integer> (); Ret.add (0);        Arrays.sort (Nums);  for(inti = 0; i < nums.length-2; i++) {Twosumsmaller (nums, I+ 1, Target-Nums[i], ret); }        returnRet.get (0); }        Private voidTwosumsmaller (int[] Nums,intIintTarget, list<integer>ret) {        intFront =i; intEnd = Nums.length-1;  while(Front <end) {            if(Nums[front] + Nums[end] <target) {Ret.set (0, Ret.get (0) + 1); End--; } Else{End--; }        }    }}

MistakesAnalysis:

Error cases:input:[3,1,0,-2], 4Output:2expected:3the above solution almost share the same code structure with 3Sum problem, excpet the condition to add"Item" into "RET" list. And we don ' t need to care about duplicates things. However, the above logic of shirking the available range is wrong for  Thisproblem. Recall, for3Sum problem, we have,---------------------------------------------------if(Nums[front] + nums[end] = =target) {... front+ + (end--); <suppose we have no duplicates>}---------------------------------------------------We can move both front and end pointers. Since"Nums[front] + nums[end] = = Target", whether we move front or end pointer, iff Nums[front_new]! = Nums[front] (which is guaranteed), we still need to move end pointer. Thus, we actually need to move both pointers forpossible available ranges, no possible answer would be skipped. but for  Thisproblem, it has great difference. Problemetic part:if(Nums[front] + Nums[end] <target) {... end--;} For above code, the end is still in available range, but we discard it, thus we lose some answers."Nums[front+1" + Nums[end] < target "May is possible. Fix:if(Nums[front] + Nums[end] <target) {... front++;}

Wrong Solution 2:

 Public classSolution { Public intThreesumsmaller (int[] Nums,inttarget) {        if(Nums = =NULL)            Throw NewIllegalArgumentException ("Nums is null"); List<Integer> ret =NewArraylist<integer> (); Ret.add (0);        Arrays.sort (Nums);  for(inti = 0; i < nums.length-2; i++) {Twosumsmaller (nums, I+ 1, Target-Nums[i], ret); }        returnRet.get (0); }        Private voidTwosumsmaller (int[] Nums,intIintTarget, list<integer>ret) {        intFront =i; intEnd = Nums.length-1;  while(Front <end) {            if(Nums[front] + Nums[end] <target) {Ret.set (0, Ret.get (0) + 1); Front++; } Else{End--; }        }    }}

MistakesAnalysis:

Error cases:input:[3,1,0,-2], 4Output:2expected:3even though we fix the problem forMoving pointer of Thisproblem, we still face the other important problem. The problem with above solution are that:use the same counting method of 3sum.problemetic part:if(Nums[front] + Nums[end] <target) {Ret.set (0, Ret.get (0) + 1); Front++;} If"Nums[front] + Nums[end] < target" is meet, all numbers from {Nums[front] to Nums[end-1]} must also meet the answer, with front fixed. Thus we should have following counting Method.ret.set (0, Ret.get (0) + End-front); Wander wheather it would incure duplicates in counting. Nope! Since after we move front++, forCeratin "Nums[i]", the same "nums[front]" would not appear again.

Analysis:

 This New genre of problem.    for (int i = 0; i < nums.length-2; i++) {    + 1, target-"Nums[front] + nums[end] Meets cert Ain condition "to control the searching in available ranges and couting right answer!!! It' s an art!!! right!

Solution:

 Public classSolution { Public intThreesumsmaller (int[] Nums,inttarget) {        if(Nums = =NULL)            Throw NewIllegalArgumentException ("Nums is null"); List<Integer> ret =NewArraylist<integer> (); Ret.add (0);        Arrays.sort (Nums);  for(inti = 0; i < nums.length-2; i++) {Twosumsmaller (nums, I+ 1, Target-Nums[i], ret); }        returnRet.get (0); }        Private voidTwosumsmaller (int[] Nums,intIintTarget, list<integer>ret) {        intFront =i; intEnd = Nums.length-1;  while(Front <end) {            if(Nums[front] + Nums[end] <target) {Ret.set (0, Ret.get (0) + End-front); Front++; } Else{End--; }        }    }}

[leetcode#259] 3Sum Smaller

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.