LeetCode第一题:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标
暴力法:
解析:遍历每个元素 x,并查找是否存在一个值与 target - x相等的目标元素。
代码如下:
//暴力匹配
public int[] twoSum(int[] nums, int target) {
for(int i = 0; i < nums.length; i++){
for(int j = i + 1; j< nums.length; j++){
if(nums[j] == target - nums[i]){
return new int[]{i ,j};//返回所求的下标
}
}
}
throw new RuntimeException("No two sum solution");
}
哈希表:
解析:因为题中需要的是数组中的元素和其索引,为了使它们一一对应,可以采用哈希表来完成具体步骤是:
1.遍历数组 nums,i 为当前下标,每个值都判断map中是否存在 target-nums[i] 的 key 值;
2.如果存在则找到了两个值,如果不存在则将当前的 (nums[i],i) 存入 map 中,继续遍历直到找到为止;
3.如果最终都没有结果则抛出异常。
代码如下:
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
if(map.containsKey(target - nums[i])) {
return new int[] {map.get(target-nums[i]),i};
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
详细的解题过程可以参见:https://leetcode-cn.com/problems/two-sum/solution/jie-suan-fa-1-liang-shu-zhi-he-by-guanpengchn/
LeetCode第27题:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度
拷贝覆盖
解析:
1.主要思路是遍历数组nums,每次取出的数字变量为num,同时设置一个下标ans;
2.在遍历过程中如果出现数字与需要移除的值不相同时,则进行拷贝覆盖nums[ans] = num,ans自增1;
3.如果相同的时候,则跳过该数字不进行拷贝覆盖,最后ans即为新的数组长度。
代码如下:
public int removeElement(int[] nums, int val) {
int ans = 0;
for(int num: nums) {
if(num != val) {
nums[ans] = num;
ans++;
}
}
return ans;
}
详细的解题过程可以参见:https://leetcode-cn.com/problems/remove-element/solution/hua-jie-suan-fa-27-yi-chu-yuan-su-by-guanpengchn/
LeetCode第35题:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
二分查找:
1.先设定左侧下标 left 和右侧下标 right,再计算中间下标 mid;
2.每次根据 nums[mid] 和 target 之间的大小进行判断,相等则直接返回下标,nums[mid] < target 则 left 右移,nums[mid] > target 则 right 左移;
3.查找结束如果没有相等值则返回 left,该值为插入位置。
代码如下:
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length;
while (left != right) {
int mid = left + (right - left) / 2;//防止溢出
if (target <= nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
还有一种较为简便的方法,因为只需要返回下标即可,因为是有序数组,我们首先判断目标值是否在数组中,如果在,返回下标即可;如果不在并且大于最后一个元素,就只需要在数组长度上加1即可。
代码如下:
public int searchInsert(int[] nums, int target) {
for(int i = 0; i < nums.length; i++){
if(nums[i] >= target){
return i;//并不是将目标数值插入到数组中
}
}
return nums.length;//如果target比数组中所有的数都大if语句就进不去了,这时就要返回到数组最后一位的后面
}
LeetCode第112题:给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
解析:二叉树由于其特殊的结构,大部分的问题都可以使用递归来解决,关于递归的理解与分析可以参见递归的解题思路,这题也不列外。深度优先遍历二叉树,每深入一次,sum-根节点的值,当到达叶子节点的时候,判断sum是否等于当前的节点值,如果等于,说明找到了,否则尝试另外一条路径。
代码如下:
boolean ans = false;
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null){
return false;
}
dfs(root, sum);
return ans;
}
public void dfs(TreeNode root, int sum){
if(root == null){
return ;
}
if(root.left == null && root.right == null){//到达叶子结点
if(sum == root.val){//关键,此时sum就是最后一个拼图,满足目标值,不然继续遍历下一条路径
ans = true;
}
}
dfs(root.left, sum - root.val);
dfs(root.right, sum - root.val);
}
详细的解题过程可以参见:https://leetcode-cn.com/problems/path-sum/solution/lu-jing-zong-he-jie-da-by-commonheart/