目录
移动零
关键是i找到0,j找到非0,此时仅i<j才移动,否则j++后重新循环。
java
public class 移动零 {
class Solution {
public void moveZeroes(int[] nums) {
int zero = 0;
int nzero = 0;
while (zero<nums.length && nzero<nums.length){
while (nums[zero]!=0){
zero++;
if (zero>= nums.length)return;
}
while (nums[nzero]==0){
nzero++;
if (nzero>= nums.length)return;
}
if (zero < nzero){
int temp = nums[zero];
nums[zero++] = nums[nzero];
nums[nzero++] = temp;
}else{
nzero++;
}
}
}
}
}
三数之和
排序+set去重 。用map记录每个元素,重复时 仅记录最后一个元素。
这题耗时太长了,但是最优解没时间看了。
java
public class 三数之和 {
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();// 对于重复元素这里只需要记最后一个index就行了
HashSet<String> set = new HashSet<>();// 用于去重
Arrays.sort(nums);
ArrayList<List<Integer>> res = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length; j++) {
if (map.containsKey(-(nums[i]+nums[j])) && map.get(-(nums[i]+nums[j]))>j){
if (!set.contains(""+nums[i]+nums[j]+(-nums[i]-nums[j]))){
ArrayList<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(-nums[i]-nums[j]);
res.add(list);
set.add(""+nums[i]+nums[j]+(-nums[i]-nums[j]));
}
}
}
}
return res;
}
}
}
盛最多水的容器
短板效应(贪心),如果移动长边那么宽度会减小,高度不变或减小,所以总的面积一定减小,只有移动短边才可能比原来的面积大,因此使用双指针向中间,不断移动短边并更新最大值。
java
public class 盛最多水的容器 {
class Solution {
public int maxArea(int[] height) {
int res = 0;
int left = 0, right = height.length - 1;
while (left < right){
res = Math.max(res, Math.min(height[left], height[right])*(right-left));
if (height[left]>height[right]) right--;
else left++;
}
return res;
}
}
}
接雨水
"盛最多水的容器"每个位置是一条边,而该问题中每个位置可以看作一个桶,计算总的接水量就是每个位置的节水量的和(由整体到分解为子问题的思想),那么每个位置的最大接水量取决于min(该位置左边的最大高度,该位置右边的最大高度)
java
public class 接雨水 {
class Solution {
public int trap(int[] height) {
int res = 0;
int[] lMax = new int[height.length + 2];
int[] rMax = new int[height.length + 2];
for (int i = 1; i <= height.length; i++) {
lMax[i] = Math.max(lMax[i-1], height[i-1]);
}
for (int i = height.length; i >= 1; i--) {
rMax[i] = Math.max(rMax[i+1], height[i-1]);
}
for (int i = 1; i <= height.length; i++) {
res += Math.max(0, Math.min(lMax[i-1], rMax[i+1]) - height[i-1]);
}
return res;
}
}
}