【代码随想录day01 |C# 704. 二分查找、27. 移除元素】

LeetCode704. 二分查找

写法一:左闭右闭

  public int Search(int[] nums, int target)
        {
        	//nums是有序的(升序)整型数组
            //左闭右闭区间,[-1,0,3,5,9,12] 实际数组与传入数组相同
            //下标从0开始计算,最右边元素的下标是nums.Length - 1;
            int right = nums.Length - 1;
            int left = 0;
            while (left <= right)//min=max 表示数组只有一个元素的时候,[1]
            {
                //int middle = (left + right) / 2;
                int middle = (left - right) / 2 + right;//有效防止left + right数值过大而造成int溢出
                // int middle= (((right - left) / 2) + left); 两种都可以
                if (nums[middle] == target)//找到目标值
                {
                    return middle;//直接结束搜索方法,返回下标
                }
                else if (nums[middle] > target)//目标值小于中间值,目标值在中间值的左边区域,重新取right值
                {
                    right = middle - 1;//因为已经确定nums[middle]不等于target且是左闭右闭的区间,所以重新取区域查找时,nums[middle]不用包含在内
                }
                else if (nums[middle] < target)//目标值大于中间值,目标值在中间值的右边区域
                {
                    left = middle + 1;
                }
            }
            return -1;
        }

写法二:左闭右开

  public int Search(int[] nums, int target)
        {
        	//nums是有序的(升序)整型数组
            //左闭右开,实际数组[-1,0,3,5,9,12,n) 最右边是开区间所以n并不能被访问到
            //传入的数组还是[-1,0,3,5,9,12]
            //下标从0开始计算,实际上最右边边元素(n)的下标是nums.Length;
            int right = nums.Length;
            int left = 0;
            while (left < right)
            //实际数组是左闭右开,不存在只有一个元素的情况,所以left不会=right,比如[1)不存在
            {
                //int middle = (left + right) / 2;
               // int middle = (left - right) / 2 + right; 会超出数组索引
                int middle= (((right - left) / 2) + left);//因为下标为right的元素访问不到,避免超出数组索引不能+right
                if (nums[middle] == target)//找到目标值
                {
                    return middle;
                }
                else if (nums[middle] > target)//目标值小于中间值,目标值在中间值的左边区域
                {
                    right = middle;//因为是左闭右开的区间,所以重新取区域查找时,nums[middle]可以包含在区间内作为最右边的元素(最右边的元素取不到)
                }
                else if (nums[middle] < target)//目标值大于中间值,目标值在中间值的右边区域,重新取left值
                {
                    left = middle + 1;//左边还是闭区间可以取到,所以nums[middle]还是不用包含在内
                }
            }
            return -1;
        }

LeetCode27. 移除元素
写法一:暴力解法(没想出来)

  public static int RemoveElement(int[] nums, int val)
        {
            int count = nums.Length;
            for (int i = 0; i < count; i++)//遍历数组寻找需要移除的元素
            {
                if (nums[i] == val)//发现需要移除的元素,将后面的元素向前移动一位
                {
                    for (int j = i+1; j< count; j++)
                    {
                        nums[j-1] = nums[j];//遍历i后面的元素
                    }
                    i--;//因为i后面的元素都往前移动了,nums[i]的元素已经更新,所以也要重新判断此时的元素是否等于val
                    count--;// 此时数组的大小-1
                }
            }
            return count;

        }

写法二:双指针(想出来了,但没想到能有这么高级的名字)

   public static int RemoveElement(int[] nums, int val)
    {
            int count = 0;
            for (int i = 0; i < nums.Length; i++)//遍历数组的元素
            {
                if (nums[i] != val)//发现不是要移除的元素就 重新 从头存入数组
                {
                    nums[count] = nums[i];
                    count++;//存了一个就+1
                }
            }
            return count;
        }

理解有误的地方求指出TAT

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值