两数之和
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>(nums.length);
for (int i = 0; i < nums.length; i++) {
int n = target - nums[i];
if (map.containsKey(n)) {
return new int[]{map.get(n), i};
}
map.put(nums[i], i);
}
return new int[0];
}
思路:将数据存储在Map中,key为具体值,value为下标,循环nums并判断是否存在target-nums[i]的值,有就取出key对于的value
盛最多水的容器
- 暴力破解
public int maxArea(int[] height) {
int maxArea = 0;
for (int i = 0; i < height.length; i++) {
for (int j = i + 1; j < height.length; j++) {
// 面积 = 最短板 * 底板;
// Math.min(height[i], height[j]):为了获取最小的一块板
// (j - i):获取两个板之间的距离,即底板长度
maxArea = Math.max(maxArea, Math.min(height[i], height[j]) * (j - i));
}
}
return maxArea;
}
- 双指针
public int maxArea(int[] height) {
// 首先将两个指针放在最左边和最右边
// 若左边的数字是否小于右边的数字,左边的向右移
// 若右边的小于左边的,右边的向左移动
int left = 0, right = height.length - 1, max = 0;
while (left < right) {
max = Math.max(max, Math.min(height[left], height[right]) * (right - left));
if (height[left] > height[right]) {
right--;
} else {
left++;
}
}
return max;
}
三数之和
// 完成时间:2021年3月7日
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if (len < 3) {
return ans;
}
// 排序
Arrays.sort(nums);
for (int i = 0; i < len; i++) {
// 因为数组已经排序,当num[i] > 0,最后的结果肯定是不等于0
if (nums[i] > 0) {
break;
}
// 当前元素与前一个元素比较,若相同需要跳过
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
// 左指针
int L = i + 1;
// 右指针
int R = len - 1;
while (L < R) {
// 得到三个值
int sum = nums[i] + nums[L] + nums[R];
if (sum == 0) {
ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
// 当前num[L]与后一个元素相同,则L++
while (L < R && nums[L] == nums[L + 1]) {
L++;
}
// 当前num[R]与前一个元素相同,则R--
while (L < R && nums[R] == nums[R - 1]) {
R--;
}
// 继续向右
L++;
// 继续向左
R--;
// sum太小,执行L++,获取更大的值
} else if (sum < 0) {
L++;
// sum太大,执行R--,获取更小的值
} else if (sum > 0) {
R--;
}
}
}
return ans;
}
思路:首先对数据排序,再获取数组中的第一个数i为基准值,获取i+1的值为第一个指针的起始点;获取size-1的值为第二个指针的起始点,依次移动。若三个值之和等于0保存这三个数,若不相等移动且sum小于0,执行L++;若sum大于0,执行R–;
最接近的三数之和
public int threeSumClosest(int[] nums, int target) {
int size = nums.length;
// 获取一个基准值
int ans = nums[0] + nums[1] + nums[2];
// 数组排序
Arrays.sort(nums);
for (int i = 0; i < size; i++) {
// 获取第一个指正的起始点
int left = i + 1;
// 获取第二个指正的起始点
int right = size - 1;
while (left < right) {
// 获取和
int sum = nums[i] + nums[left] + nums[right];
// 比较sum与基准值的差值
if (Math.abs(target - sum) < Math.abs(target - ans)) {
// 更新和
ans = sum;
// 和太小,第一个指针向右移
} else if (sum < 0) {
left++;
// 和太大,第二个指针向左移
} else if (sum > 0) {
right--;
}
}
}
return ans;
}
思路:分别获取左指针和右指针,通过判断sum的大小来调整指针的移动