LeetCode每日一解

本着练习的目的,建议不要取巧,胜一时易,时时胜难

1.从排序数组中删除重复项

难点:

nums去重之后为什么会改变数组大小 ?what? val是去重后的索引,但nums是素组啊,打印这个索引出现了数组  

个人理解:

// 我是长度,超过的删除
int len = removeDuplicates(nums);

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);


public class Solution {
    public int RemoveDuplicates(int[] nums) {
        
        if(nums.Length<=0)
        {
            return 0;
        }
        int val=0;
        //排序
        for(int i=0;i<nums.Length;i++)
        {
            if(nums[i]!=nums[val])
            {
                //出现新的数 給个位置
                val++;
                nums[val]=nums[i];
            }
        }
//索引从0开始,补齐数组长度
        val+=1;
//nums去重之后为什么会改变数组大小 ?what? val是去重后的索引,但nums是素组啊,打印这个索引出现了数组  
        return val;
    }
}

2.寻找数组的中心索引

难点:尽量少的使用for循环

public class Solution {
    public int PivotIndex(int[] nums) {
        int  outStr= -1; 
        int num1=0;;
        for(int i=0;i<nums.Length;i++)
        {
            num1+=nums[i];
        }


        for(int i=0;i<nums.Length;i++)
        {
            int num=0;
            //不能使用left= (sum-i)/2
            for(int j=0;j<i;j++)
            {
                num+=nums[j];
            }
            if(num*2 +nums[i]==num1)
            {
                outStr =i;
                break;
            }
            
        }
        return outStr;
    }
}

3.买卖股票的最佳时机 II

三种解法

https://blog.csdn.net/qq_27480345/article/details/86490478

难点:

1.卖出当天依然可以买入

2.哪天买卖最合适,不是单天最大收益,而是累计最大收益;

3.利益差的递增(只要能交易就进行利益差的累加)

  public int MaxProfit(int[] prices) {
   
        int sum=0;
        //假设第二天开始卖出
        for(int i=1;i<prices.Length;i++)
        {
            //是否可以卖出
             if(prices[i]>prices[i-1])
             {
                //计算所有收益,并进行累加
                 sum+=prices[i]-prices[i-1];
             }
        }
        return sum;
        
    }

4.旋转数组

难点:不知道为什么要叫旋转数组,利用取余重新设定数组的索引

        var nums = arry;
        int k = 3;
        //超出取余
        k %= nums.Length;

        int[] arr = new int[nums.Length];
        int n = nums.Length;
        for (int i = 0; i < nums.Length; i++)
        {
            //从目标位置重新排序
            arr[(i + k) % n] = nums[i];
        }
        arr.CopyTo(nums, 0);

5.存在重复元素

public class Program {
 
    public static void Main(string[] args) {
        int[] nums = null;
 
        nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 7 };
        var res = ContainsDuplicate(nums);
        Console.WriteLine(res);
 
        nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        res = ContainsDuplicate2(nums);
        Console.WriteLine(res);
 
        nums = new int[] { 1, 2, 3, 3, 5, 6, 7, 8 };
        res = ContainsDuplicate3(nums);
        Console.WriteLine(res);
 
        Console.ReadKey();
    }
 
    private static bool ContainsDuplicate(int[] nums) {
        //暴力解法
        for(int i = 0; i < nums.Length; i++) {
            for(int j = i + 1; j < nums.Length; j++) {
                if(nums[i] == nums[j]) return true;
            }
        }
        return false;
    }
 
    private static bool ContainsDuplicate2(int[] nums) {
        //先排序,再使用单循环比较相邻值
        Array.Sort(nums);
        for(int i = 0; i < nums.Length - 1; i++) {
            if(nums[i] == nums[i + 1]) return true;
        }
        return false;
    }
 
    private static bool ContainsDuplicate3(int[] nums) {
        //哈希法
        var dic = new Dictionary<int, int>();
        foreach(var num in nums) {
            if(dic.ContainsKey(num)) return true;
            dic[num] = 0;
        }
        return false;
    }
 
}

6.只出现一次的数字

 线性时间复杂度:要求我们的代码时间复杂度最高为O(n),不能有嵌套循环等。

   不使用额外空间:要求空间复杂度最高为O(1)。

方法一(比较法):
public static int singleNumber(int[] nums) {
        Arrays.sort(nums);  
// 排序数组  思路:先对数组进行排序,然后对 nums[i] 和 nums[i + 1]进行比较,如相等,i += 2继续下一组比较,直到取到不相等的一组。
        for (int i = 0; i < nums.length - 1; i += 2) {
            // 找到不相等的一组,直接返回
            if (nums[i] != nums[i + 1]) {
                return nums[i];
            }
        }
        // 如果没有找到不相等的一组数据,直接返回数组的最后一个数字
        return nums[nums.length - 1];
    }

方法二(去重法):

思路:利用HashSet的特性,删除重复的数组元素,最后剩下一个单独的元素,返回即可。
public static int singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            if (!set.add(nums[i])) { // add成功返回true,如果set中已有相同数字,则add方法会返回false
                set.remove(nums[i]); // 删除重复出现的数字
            }
        }
        return set.iterator().next();9     }
方法三(求差法):

  思路:先对数组排序,显而易见的,单独出现一次的数据必然是出现在数组下标为偶数的位置(下标从0开始),那么所有奇数下标的元素之和减去偶数下标的元素之和,就是需要求得的结果。
public static int singleNumber(int[] nums) {
        int num = 0;
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            // 偶数下标位置 num += nums[i],奇数下标位置 num -= nums[i]
            num = i % 2 == 0 ? num + nums[i] : num - nums[i];
        }
        return num;
    }
方法四(异或法):

  思路:根据异或运算的特点,相同的数字经过异或运算后结果为0,除单独出现一次的数字外,其他数字都是出现两次的,那么这些数字经过异或运算后结果一定是0。而任何数字与0进行异或运算都是该数字本身。所以对数组所有元素进行异或运算,运算结果就是题目的答案。
public static int singleNumber(int[] nums) {
        int num = 0;
        for (int i = 0; i < nums.length; i++) {
            num = num ^ nums[i];
        }
        return num;
    }
发布了54 篇原创文章 · 获赞 37 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/osuckseed/article/details/103840323