开学大三,第一次系统学习算法知识,参加了Carl哥的算法训练营,虽然题很基础,但是好久没有练习,还是有一些生疏的感觉,继续加油
想到了一个道理:代码是为了用计算机语言来实现我们的数学思想
704. 二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
因为是科班出身,刚刚看到题目的时候有一种陌生的熟悉感,瞎写了半天,写出来了一个奇怪的代码,检查了两遍,发现忘记打括号了。
①左闭右闭区间
class Solution {
public int search(int[] nums, int target) {
int left=0;
int right=nums.length-1;
int mid=0;
while(left <= right){
mid=(left+right)/2;
if(nums[mid] > target){
right=mid-1;
}else if(nums[mid] < target){
left=mid+1;
}else{
return mid;
}
}
return -1;
}
}
二分查找法是最简单的搜索算法之一,不过不要忘记特别需要注意的点,边界值的选取
当区间左右均为闭区间,说明可以取左右两端值相等的情况,while(left ? right),为了不丢数值且合法,此时填写<=
此时数值在mid值左侧部分,则需考虑right的边界值取值。
代码if(nums[mid] > target)说明,mid一定不是我们的所需值,所以right的边界取值一定不要包含mid的值。(将mid置入,相当于把不是自己的值加入到里面,边界处理出现问题)
②左闭右开区间
class Solution {
public int search(int[] nums, int target) {
int left=0;
int right=nums.length;
int mid;
while(left < right){
mid=(right+left)/2;
if(nums[mid] > target){
right=mid;
}else if(nums[mid] < target){
left=mid+1;
}else if(nums[mid]==target){
return mid;
}
}
return -1;
}
}
拟定左闭右开区间,左边界0,右边界nums.length
while(left < right)左闭右开
if(nums[mid] > target)按照大小比较得出值在mid左侧,需要修改右区间,为了合法性右侧为开区间所以right=mid合法,即可添加值
27.移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
①暴力解法
class Solution {
public int removeElement(int[] nums, int val) {
int numslength=nums.length;
for(int i=0;i<numslength;i++){
if(nums[i]==val){
for(int j=i+1;j<numslength;j++){
nums[j-1]=nums[j];
}
i--;
numslength--;
}
}
return numslength;
}
}
根据卡哥说的先写了一遍暴力解法,这点代码调了半个多小时,还是好生疏
②双指针法
class Solution {
public int removeElement(int[] nums, int val) {
int size=nums.length;
int slowindex=0;
for(int fastindex=0;fastindex<nums.length;fastindex++){
if(nums[fastindex]!=val){
nums[slowindex++]=nums[fastindex];
}else{
size--;
}
}
return size;
}
}
原理弄懂了,自己能够复现,但是思路感觉想不到,有点数学的感觉了,还是要多加思考,利用两个指针进行覆盖运算,对于为了数组以及链表操作都有作用。