leetcode 1 号算法题:两数之和
leetcode 167 号算法题:两数之和Ⅱ - 输入有序数组
leetcode 170 号算法题:两数之和Ⅲ - 数据结构设计
leetcode 653 号算法题:两数之和Ⅳ - 输入 BST
leetcode 15 号算法题:三数之和
leetcode 18 号算法题:四数之和
培养算法思维【逐渐优化,一直到最优】提升编程内功 - 两数之和
文章目录
leetcode 1 号算法题:两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums==null||nums.length<=0)
return new int[0];
int n=nums.length;
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<n;i++){
int x=nums[i];
if(map.containsKey(target-x)){
int index=map.get(target-x);
return new int[]{i,index};
}
map.put(x,i);
}
return new int[0];
}
}
leetcode 167 号算法题:两数之和Ⅱ - 输入有序数组
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
class Solution {
public int[] twoSum(int[] numbers, int target) {
if(numbers==null||numbers.length<=0)
return new int[0];
for(int i=0;i<numbers.length;i++){
int x=numbers[i];
int index=binarySearch(i+1,numbers.length-1,numbers,target-x);
if(index!=-1)
return new int[]{i+1,index+1};
}
return new int[0];
}
private int binarySearch(int left,int right,int [] numbers,int target){
while(left<=right){
int mid=(left+right)/2;
if(numbers[mid]==target)
return mid;
else if(numbers[mid]>target)
right=mid-1;
else
left=mid+1;
}
return -1;
}
}
leetcode 170 号算法题:两数之和Ⅲ - 数据结构设计
设计一个接收整数流的数据结构,该数据结构支持检查是否存在两数之和等于特定值。
实现 TwoSum 类:
TwoSum() 使用空数组初始化 TwoSum 对象
void add(int number) 向数据结构添加一个数 number
boolean find(int value) 寻找数据结构中是否存在一对整数,使得两数之和与给定的值相等。如果存在,返回 true ;否则,返回 false
O(nlogn)方法:
class TwoSum {
private List<Integer> list;
boolean isSorted;
/** Initialize your data structure here. */
public TwoSum() {
list=new ArrayList<>();
isSorted=false;
}
/** Add the number to an internal data structure.. */
public void add(int number) {
list.add(number);
isSorted=false;
}
/** Find if there exists any pair of numbers which sum is equal to the value. */
public boolean find(int value) {
if(isSorted==false){
Collections.sort(list);
isSorted=true;
}
int left=0;
int right=list.size()-1;
while(left<right){
int sum=list.get(left)+list.get(right);
if(sum==value){
return true;
}else if(sum<value){
left++;
}else{
right--;
}
}
return false;
}
}
O(n)方法:
class TwoSum {
Map<Integer,Integer> map;
/** Initialize your data structure here. */
public TwoSum() {
map=new HashMap<>();
}
/** Add the number to an internal data structure.. */
public void add(int number) {
map.put(number,map.getOrDefault(number,0)+1);
}
/** Find if there exists any pair of numbers which sum is equal to the value. */
public boolean find(int value) {
for(Integer num:map.keySet()){
int target=value-num;
if(num==target&&map.get(target)>1)return true;
if(num!=target&&map.containsKey(target))return true;
}
return false;
}
}
leetcode 653 号算法题:两数之和Ⅳ - 输入 BST
class Solution {
public boolean findTarget(TreeNode root, int k) {
List<Integer> list=new ArrayList<>();
if(root==null)
return false;
inOrder(root,list);
int left=0,right=list.size()-1;
while(left<right){
int sum=list.get(left)+list.get(right);
if(sum==k){
return true;
}else if(sum<k){
left++;
}else{
right--;
}
}
return false;
}
private void inOrder(TreeNode root,List<Integer> list){
if(root!=null){
inOrder(root.left,list);
list.add(root.val);
inOrder(root.right,list);
}
}
}
leetcode 15 号算法题:三数之和
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
if(nums==null||nums.length<=0)
return new ArrayList<>();
Set<List<Integer>> set=new HashSet<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
int value=-nums[i];
int left=i+1,right=nums.length-1;
while(left<right){
int sum=nums[left]+nums[right];
if(sum==value){
set.add(Arrays.asList(value*-1,nums[left],nums[right]));
left++;
right--;
}else if(sum>value){
right--;
}else{
left++;
}
}
}
return new ArrayList<>(set);
}
}
leetcode 18 号算法题:四数之和
错误:
class Solution {
private List<List<Integer>> threeSum(int[] nums,int target,int begin,int end){
Set<List<Integer>> three_set=new HashSet<>();
for(int i=begin;i<end;i++){
int value=target-nums[i];
int left=begin+1,right=end;
while(left<right){
int sum=nums[left]+nums[right];
if(sum==value){
three_set.add(Arrays.asList(value*-1,nums[left],nums[right]));
left++;
right--;
}else if(sum<value){
left++;
}else{
right--;
}
}
}
return new ArrayList<>(three_set);
}
public List<List<Integer>> fourSum(int[] nums, int target) {
if(nums==null||nums.length<=0)
return new ArrayList<>();
Set<List<Integer>> four_set=new HashSet<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
int value=target-nums[i];
int left=i+1,right=nums.length-1;
List<List<Integer>> list=threeSum(nums,value,left,right);
if(!list.isEmpty()){
for(int j=0;j<list.size();j++){
List<Integer> list_temp=list.get(j);
list_temp.add(value*-1);
four_set.add(list_temp);
}
}
}
return new ArrayList<>(four_set);
}
}
正确:
public List<List<Integer>> fourSum(int[] nums, int target) {
if (nums == null || nums.length < 4)
return new ArrayList<>();
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
// O(n^3)
for (int i = 0; i < nums.length - 3; i++) {
// 忽略后面与前面重复的元素
if (i > 0 && nums[i] == nums[i - 1]) continue;
for (int j = i + 1; j < nums.length - 2; j++) {
// 忽略后面与前面重复的元素
if (j > i + 1 && nums[j] == nums[j - 1]) continue;
int partSum = nums[i] + nums[j];
int left = j + 1;
int right = nums.length - 1;
while (left < right) {
int sum = partSum + nums[left] + nums[right];
if (sum > target) {
right--;
} else if (sum < target) {
left++;
} else {
res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
while (left < right && nums[left] == nums[++left]);
while (left < right && nums[right] == nums[--right]);
}
}
}
}
return res;
}