Leetcode数组简单题

序号为前200的数组简单题

  • 前言
  • 一、两数之和
  • 二、删除有序数组中的重复项
  • 三、移除长度
  • 四、搜索插入位置
  • 五、最大子序和
  • 六、加一
  • 七、合并两个有序数组
  • 八、杨辉三角
  • 九、杨辉三角II
  • 十、买卖股票的最佳时机
  • 十一、买卖股票的最佳时机 II
  • 十二、两数之和 II- 输入有序数组
  • 十三、多数元素
  • 十四、存在重复元素
  • 十五、旋转数组


前言

本文包含了十几道leetcode上数组的简单题,记录在此,希望以后在做题道路上也能一帆风顺,做题不再犯愁!!!


一、两数之和

leetcode 01 题目链接

第一种暴力的方法直接双for循环时间复杂度为O(N^2) 效果不太好
代码如下(示例):

 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[i]+nums[j]==target){
                    return new int[]{i,j};
                }
            }
        }
  return new int[]{};

第二种利用map存储值和下标位置 遍历一边就可以了 时间复杂度为O(N)
代码如下(示例):

 public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map=new HashMap<>();
        map.put(nums[0],0);
        for(int i=0;i<nums.length;i++){
            int count=target-nums[i];
            if(map.containsKey(count)){
                int index1=map.get(count);
                int index2=i;
                return new int[]{index1,index2};
            }else {
                map.put(nums[i],i);
            }

        }
        return null;
    }

二、删除有序数组中的重复项

leetcode 26 题目链接

定义快慢指针 慢指针返回不重复数组长度的下标,快指针定义要交换的位置
代码如下(示例):

  public int removeDuplicates(int[] nums) {
        if(nums.length==0){
            return 0;
        }
        //用快慢指针
        int fast=1;//要检测的位置
        int slow=0;//交换位置 或者返回长度位置
       while(fast<nums.length){
            if(nums[slow]!=nums[fast]){
                nums[slow+1]=nums[fast];
                slow++;
            }
            fast++;  
            }
        return slow+1;
    }

三、移除长度

leetcode 27 题目链接
代码如下(示例):

 public int removeElement(int[] nums, int val) {
       // i  检验是否==val 等于跳过 不等于赋值
        //j 为计数位置
    int j=0;
    for(int i=0;i<nums.length;i++){
        if(nums[i]!=val){
            nums[j]=nums[i];
            j++;
        }
    }
    return j;
    }

四、搜索插入位置

leetcode 35 题目链接
该题很容易想,直接遍历一边就行了 ,如果遇到比目标值大的返回该下标就好了,如果一直没有就插入到最后一个位置即可。
代码如下(示例):

 public int searchInsert(int[] nums, int target) {
       for(int i=0;i<nums.length;i++){
            if(nums[i]==target){
                return i;
            }
            if(nums[i]>target){
                return i;
            }
            
        }
        return nums.length;
    }

五、最大子序和

leetcode 53 题目链接
这道题呢是求出最大子序列的和,可以定义双变量,一个存储最大值(max),另一个是累加和(count)
注意:不能将max和count 定义为0;可能是全负序列。
遍历的过程中,max一直存储的是最大值,count如果变为负数就重新计数累加即可找到最大值。
代码如下(示例):

public int maxSubArray(int[] nums) {
  int count=nums[0];
        int max=nums[0];
        for(int i=1;i<nums.length;i++){
            if(count<0){
                count=nums[i];
            }else {
                count+=nums[i];
            }
            max=Math.max(count,max);
     }
        return max;
    }

六、加一

leetcode 66 题目链接

这道题刚开始没有理解意思,以为就是简单往最后一个元素加一,报错才发现还有进制,那就多加一位首位为1就好了。
代码如下(示例):

 public int[] plusOne(int[] digits) {
        for(int i=digits.length-1;i>=0;i--){
            digits[i]++;
            digits[i]=digits[i]%10;//如果为9 最后一位会变成0 然后给首位加1就可 全是9的序列会变成全为0
            if(digits[i]%10!=0){
                return digits;
            }
        }
        digits=new int[digits.length+1];
        digits[0]=1;
        return digits;
    }

七、合并两个有序数组

leetcode 88 题目链接

这道题我先看了看,想了一个偷懒的办法,就是将第二个数组放到第一个数组0元素的位置,之后将数组排序

 public void merge(int[] nums1, int m, int[] nums2, int n) {
      for(int i=0;i<nums2.length;i++){
          nums1[m]=nums2[i];
          m++;
      }
      Arrays.sort(nums1);
}

之后想了半天从前面排了很久,也没排好主要不想建立一个新的数组,就去看了官方的题解,竟然从后往前找,逆向思维,太牛了!!!
接近双百

public void merge(int[] nums1, int m, int[] nums2, int n) {
     int i=m-1;
     int j=n-1;
     int k=m+n-1;
     while(i>=0&&j>=0){
         if(nums1[i]>nums2[j]){
             nums1[k--]=nums1[i--];
         }else{
             nums1[k--]=nums2[j--];
         }
     }
     while(j>=0){//即nums2元素还没放完
     nums1[k--]=nums2[j--];
       }
}

八、杨辉三角

leetcode 118 题目链接

每一列的第一个和最后一个元素都是1
每一行不是1的值都是由其正上方和正上方左边元素相加。

 public List<List<Integer>> generate(int numRows) {
       List<List<Integer>> list=new ArrayList<>();
       int [][]array=new int[numRows][numRows];
       for(int i=0;i<numRows;i++){
         List<Integer> temp=new ArrayList<>();
         for(int j=0;j<=i;j++){
             if(j==0||i==j){
                 array[i][j]=1;
             }else{
                 array[i][j]=array[i-1][j-1]+array[i-1][j];
             }
             temp.add(array[i][j]);
          }
          list.add(temp);
       }
       return list;
}

九、杨辉三角II

leetcode 119 题目链接

杨辉三角的变形题目

  public List<Integer> getRow(int rowIndex) {
        int[] array = new int[rowIndex + 1];
             array[0] = 1;
        for (int i = 1; i < rowIndex + 1; i++) {
        for (int j = i; j >= 0; j--) {
            if (j - 1 >= 0) array[j] += array[j - 1];
            if (array[j] == 0) array[j] = 1;
        }
    }
    List<Integer> ans = new ArrayList<>();
        for (int i = 0; i < rowIndex + 1; i++) ans.add(array[i]);
        return ans;
    }

十、买卖股票的最佳时机

leetcode 121 题目链接

先用了双for暴力法,发现超时了,最后看了官方的题解也有双for
接下来用一次遍历的方法,每次取存储的最小值,用当前值去减去存储在max中即可

public int maxProfit(int[] prices) {
      int max=0;
     int temp=prices[0];
     for(int i=1;i<prices.length;i++){
         temp=Math.min(prices[i],temp);
         max=Math.max(max,prices[i]-temp);
     }
      return max;
    }

十一、买卖股票的最佳时机 II

leetcode 122 题目链接

遍历一边求最大值差值 将最大差值分解为每一个小部分相加即可。

    public int maxProfit(int[] prices) {
        int profit=0;
        for(int i=1;i<prices.length;i++){
                if(prices[i]-prices[i-1]>0){
                    profit+=prices[i]-prices[i-1];
                  }

        }
        return profit;
}

十二、两数之和 II- 输入有序数组

leetcode 167 题目链接

这题还是很简单的,先暴力算法 时间复杂度O(n^2) 只超过5%。。。

 public int[] twoSum(int[] numbers, int target) {
       for(int i=0;i<numbers.length;i++){
           for(int j=i+1;j<numbers.length;j++){
               if(numbers[i]+numbers[j]==target){
                   i+=1;
                   j+=1;
                   return new int[]{i,j};
               }
           }
       }
        return null;
    }

双指针 只遍历一边,很快。

 public int[] twoSum(int[] numbers, int target) {
        int i=0;
           int j=numbers.length-1;
       for(int num:numbers){
           if(numbers[i]+numbers[j]>target){
               j--;
           }else if(numbers[i]+numbers[j]<target){
               i++;
           }else{
               break;
           }
       }
       return new int[]{i+1,j+1};
    }

十三、多数元素

leetcode 169 题目链接

这道题就是返回数组中元素个数超过一般的元素,最开始的思想就是暴力双for循环比较,感觉自己太笨了,什么都是双for,直接将时间复杂度拉满,只超过5%的用户

代码如下(示例):

public int majorityElement(int[] nums) {
     if(nums.length==1){
         return nums[0];
     }
     int count=1; int max=0;
     for(int i=0;i<nums.length;i++){
         for(int j=0;j<nums.length;j++){
        if(nums[i]==nums[j]&&i!=j){
            count++;
            if(count>nums.length>>1){
                return nums[j];
            }
        }
      }
           count=1;
    }
    return 0;
  }

看完评论后我看到有人两行代码也能过, 最多的数字长度超过长度的一半,返回排好序的中间位置就好了。

public int majorityElement(int[] nums) {
       Arrays.sort(nums);
       return nums[nums.length>>1];
    }
 } 

最后才发现这题是摩尔投票法,核心就是对撞互拼,挺有趣的 ,在评论区看见一个大神写的双百做法,挺巧妙的。

public int majorityElement(int[] nums) {
    int count=0;
    int last=0;
    for(int num:nums){
        if(count==0){
            last=num;
        }
        count=count+(last==num?1:-1);
    }
    return last;
  }

十四、存在重复元素

leetcode 217

这道题很好写直接排序,遍历就完事了 接近双百的做法

 public boolean containsDuplicate(int[] nums) {
        Arrays.sort(nums);
        for(int i=1;i<nums.length;i++){
            if(nums[i]==nums[i-1]){
                return true;
            }
        }
        return false;
 }

可能做数组的题的时候排序不太好,就又写了一种用set的方法

        public boolean containsDuplicate(int[] nums) {
         Set<Integer> set= new HashSet<>();
        for(int i=0;i<nums.length;i++){
            if(set.contains(nums[i])){
                return true;
            }
            set.add(nums[i]);
        }
        return false;
 }

但是用set慢了一点。

十五、旋转数组

leetcode 189

这道题开始O(1)空间复杂度不容易想,先用O(n)做,创建一个新数组

 public void rotate(int[] nums, int k) {
        int []array=new int[nums.length];
        for(int i=0;i<nums.length;i++){
            array[(i+k)%nums.length]=nums[i];
        }
        System.arraycopy(array, 0, nums, 0, nums.length);
    }

最后看了题解才发现旋转就完事了

public void rotate(int[] nums, int k) {
        int n=nums.length;
        k%=n;//必须加上,测试用例中会给超出长度的k
        func(nums,0,n-1);
        func(nums,0,k-1);
        func(nums,k,n-1);
  }private void func(int [] nums,int left,int right){
       while(left<right){
           int temp=nums[left];
           nums[left]=nums[right];
           nums[right]=temp;
           left++;
           right--;
       }
 }

你可能感兴趣的:(Leetcode,java)