1.3sum
![](https://i-blog.csdnimg.cn/blog_migrate/149afa3ae0d5ccc59252b194291226ff.png)
根据题目的要求,需要按顺序输出,并且不重复,那么可以先将数组s进行排序,这可以保证输出结果是按顺序的,然后通过hashmap对每种新结果进行存储,如果有重复就不再存储。接着便是可以通过将数字进行存储进hash表,用两个循环进行遍历,前两个数确定之后,第三个数用hash进行查找。
import java.util.*;
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();
HashMap<Integer,Integer> hm=new HashMap();
HashMap<String,Integer> hm1=new HashMap();
int n=num.length;
for(int i=0;i<n;i++)
{
if(hm.containsKey(num[i])&&hm.get(num[i])<3)
hm.put(num[i], hm.get(num[i])+1);
else if(!hm.containsKey(num[i]))
hm.put(num[i], 1);
}
Arrays.sort(num);
int i=0;
int j;
int target;
while(i<n)
{
j=i+1;
while(j<n)
{
target=-(num[i]+num[j]);
ArrayList<Integer> list1=new ArrayList<Integer>();
int[] temp= {num[i],num[j],target};
Arrays.sort(temp);
String s=""+temp[0]+temp[1]+temp[2];
if(hm.containsKey(target))
{
if(num[i]==num[j])
{
if(num[i]==target)
{
if(hm.get(num[i])==3&&!hm1.containsKey(s))
{
list1.add(temp[0]);
list1.add(temp[1]);
list1.add(temp[2]);
hm1.put(s, 1);
}
}
else
{
if(hm.get(num[i])>=2&&!hm1.containsKey(s))
{
list1.add(temp[0]);
list1.add(temp[1]);
list1.add(temp[2]);
hm1.put(s, 1);
}
}
}
else
{
if(num[i]==target)
{
if(hm.get(num[i])>=2&&!hm1.containsKey(s))
{
list1.add(temp[0]);
list1.add(temp[1]);
list1.add(temp[2]);
hm1.put(s, 1);
}
}
else if(num[j]==target)
{
if(hm.get(num[j])>=2&&!hm1.containsKey(s))
{
list1.add(temp[0]);
list1.add(temp[1]);
list1.add(temp[2]);
hm1.put(s, 1);
}
}
else
{
if(!hm1.containsKey(s))
{
list1.add(temp[0]);
list1.add(temp[1]);
list1.add(temp[2]);
hm1.put(s, 1);
}
}
}
}
if(!list1.isEmpty())
list.add(list1);
int k=num[j];
while(j<n&&k==num[j])
j++;
}
int t=num[i];
while(i<n&&t==num[i])
i++;
}
return list;
}
}
2.3sum-closest
![](https://i-blog.csdnimg.cn/blog_migrate/591ac52f71df6ea0b021bd6105efbe08.png)
求最接近的三个数的和,则可以采用贪心算法,先对数组进行排序,然后遍历。
import java.util.*;
public class Solution {
public int threeSumClosest(int[] num, int target) {
int n=num.length;
int ans=0;
Arrays.sort(num);
int tmp=Integer.MAX_VALUE;
out:
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n-1;j++)
{
int res=target-(num[i]+num[j]);
int index=Arrays.binarySearch(num, j+1, n, res);
if(index>j)
{
ans=num[index]+num[i]+num[j];
break out;
}
else
{
int t1=-index-1;
int t2=-index-2;
if(t1==j+1)
{
if(Math.abs(num[t1]-res)<tmp)
{
tmp=Math.abs(num[t1]-res);
ans=num[t1]+num[i]+num[j];
}
}
else
{
if(t1<n)
{
if(Math.abs(num[t1]-res)<tmp)
{
tmp=Math.abs(num[t1]-res);
ans=num[t1]+num[i]+num[j];
}
}
if(t2<n)
{
if(Math.abs(num[t2]-res)<tmp)
{
tmp=Math.abs(num[t2]-res);
ans=num[t2]+num[i]+num[j];
}
}
}
}
}
}
return ans;
}
}
3.remove-nth-node-from-end-of-list
![](https://i-blog.csdnimg.cn/blog_migrate/ea41a785abd859f134a30e500fa07d4f.png)
删除倒数第n个结点,是比较经典的有关链表的题目,思路可以使用快慢指针的思路,需要注意的就是结点个数的统计,为了便于结点个数的统计,这里添加了一个伪头指针。让快指针从伪头指针开始走n个,然后慢指针从伪头指针开始与快指针一起走,直到快指针指向null。为了便于操作,本文使用的方法中,是先让快指针走n-1个结点,那么这样可以找到被删除结点的前一个节点,然后找到被删除结点后一个结点,两者连接起来,便将目标结点删除了。
public class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode node=new ListNode(-1);
node.next=head;
ListNode pre=node;
ListNode res=node;
int i=0;
while(pre.next!=null&&i<n)
{
pre=pre.next;
i++;
}
while(pre.next!=null)
{
res=res.next;
pre=pre.next;
}
ListNode temp=res;
res=res.next;
ListNode ans=res.next;
temp.next=ans;
return node.next;
}
4.valid-parentheses
![](https://i-blog.csdnimg.cn/blog_migrate/93c1166ee6a13d283da25d64ac31b516.png)
这是判断括号是否合法,括号一般都会使用栈,由于这里涉及了三种括号,便于查询,将它们存入hashmap中,一半作为键,一半作为值。然后开始遍历字符串,如果栈是空的,则往栈里放当前字符;如果不是空的,则需要看看当前字符和栈顶字符是否配对,如果配对则将栈顶字符pop出,如果不是配对的话,将当前字符存入栈。直到遍历结束,检查栈是否为空,如果为空,则说明合法,反之不合法。
import java.util.*;
public class Solution {
public boolean isValid(String s) {
Stack<String> stack=new Stack<String>();
int n=s.length();
HashMap<String,String> hm=new HashMap();
hm.put("{", "}");
hm.put("}","{");
hm.put("[","]");
hm.put("]", "[");
hm.put(")","(");
hm.put("(",")");
for(int i=0;i<n;i++)
{
if(!stack.isEmpty())
{
String cr=stack.lastElement();
if(cr.equals(hm.get(s.charAt(i)+"")))
stack.pop();
else
stack.push(s.charAt(i)+"");
}
else
{
stack.push(s.charAt(i)+"");
}
}
if(stack.isEmpty())
return true;
return false;
}
}
5.generate-parentheses
![](https://i-blog.csdnimg.cn/blog_migrate/91bca86bfe898f2236f33c082d897bc2.png)
这是给出n对括号,求可能的配对方式,并按字典序输出。这里可以用递归的方式求,首先左括号和右括号各有n,开始一个个安放,先放左括号,然后放右括号;注意剪枝以及递归终止条件,因为要输出结果,所以需要一个字符串存储结果,并用list保存。当左右括号都为0的时候将当前方案存入list中。如果出现不合法现象则进行剪枝,比如左括号或右括号小于0,或者剩余左括号大于剩余右括号。代码如下:
import java.util.*;
public class Solution {
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> list = new ArrayList<String>();
getList(n, n, "", list);
return list;
}
public void getList(int left, int right,String out,ArrayList<String> list) {
if(left<0||right<0||left>right) return;
if(left==0&&right==0) {
list.add(new String(out));
return;
}
getList(left-1, right, out+"(", list);
getList(left, right-1, out+")", list);
}
}