九日集训第三天(一维数组)

一、前言

九日集训第三天。

二、题目

1)33. 搜索旋转排序数组

  整数数组 n u m s nums nums 按升序排列,数组中的值 互不相同 。在传递给函数之前, n u m s nums nums 在预先未知的某个下标 k ( 0 < = k < n u m s . l e n g t h ) k(0 <= k < nums.length) k0<=k<nums.length上进行了 旋转,使数组变为 [ n u m s [ k ] , n u m s [ k + 1 ] , . . . , n u m s [ n − 1 ] , n u m s [ 0 ] , n u m s [ 1 ] , . . . , n u m s [ k − 1 ] ] [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] [nums[k],nums[k+1],...,nums[n1],nums[0],nums[1],...,nums[k1]](下标 从 0 0 0 开始 计数)。例如, [ 0 , 1 , 2 , 4 , 5 , 6 , 7 ] [0,1,2,4,5,6,7] [0,1,2,4,5,6,7] 在下标 3 3 3 处经旋转后可能变为 [ 4 , 5 , 6 , 7 , 0 , 1 , 2 ] [4,5,6,7,0,1,2] [4,5,6,7,0,1,2] 。给你 旋转后 的数组 n u m s nums nums 和一个整数 t a r g e t target target ,如果 n u m s nums nums 中存在这个目标值 t a r g e t target target ,则返回它的下标,否则返回 − 1 -1 1

1.a)题目分析:

  由于本题是返回的下标为旋转后的数组的下标,所以可以不考虑升序排列的数组,直接使用 f o r for for循环遍历数组,并与整数 t a r g e t target target 进行比较,从而得到结果。

1.b)代码:

class Solution {
    public int search(int[] nums, int target) {
        int n = nums.length;
        for(int i= 0;i<n;i++){
            if(nums[i]==target){
                return i;
            }
        }
      return -1;  
    }
}

2)81.搜索旋转排序数组 II

已知存在一个按非降序排列的整数数组 n u m s nums nums ,数组中的值不必互不相同。在传递给函数之前, n u m s nums nums 在预先未知的某个下标 k ( 0 < = k < n u m s . l e n g t h ) k(0 <= k < nums.length) k0<=k<nums.length上进行了 旋转 ,使数组变为 [ n u m s [ k ] , n u m s [ k + 1 ] , . . . , n u m s [ n − 1 ] , n u m s [ 0 ] , n u m s [ 1 ] , . . . , n u m s [ k − 1 ] ] [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] [nums[k],nums[k+1],...,nums[n1],nums[0],nums[1],...,nums[k1]](下标 从 0 0 0 开始 计数)。例如, [ 0 , 1 , 2 , 4 , 4 , 4 , 5 , 6 , 6 , 7 ] [0,1,2,4,4,4,5,6,6,7] [0,1,2,4,4,4,5,6,6,7] 在下标 5 5 5 处经旋转后可能变为 [ 4 , 5 , 6 , 6 , 7 , 0 , 1 , 2 , 4 , 4 ] [4,5,6,6,7,0,1,2,4,4] [4,5,6,6,7,0,1,2,4,4] 。给你 旋转后 的数组 n u m s nums nums 和一个整数 t a r g e t target target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 n u m s nums nums在这个目标值 t a r g e t target target ,则返回 t r u e true true ,否则返回 f a l s e false false

2.a)题目分析:

  本题与上题类似,只是在返回值上有所变化。

2.b)代码:

class Solution {
    public boolean search(int[] nums, int target) {
        int n = nums.length;
        for(int i= 0;i<n;i++){
            if(nums[i]==target){
                return true;
            }
        }
      return false;  
    }
}

3)153. 寻找旋转排序数组中的最小值

  已知一个长度为 n n n 的数组,预先按照升序排列,经由 1 1 1 n n n 次 旋转 后,得到输入数组。例如,原数组 n u m s = [ 0 , 1 , 2 , 4 , 5 , 6 , 7 ] nums = [0,1,2,4,5,6,7] nums=[0,1,2,4,5,6,7] 在变化后可能得到:
    若旋转 4 4 4 次,则可以得到 [ 4 , 5 , 6 , 7 , 0 , 1 , 2 ] [4,5,6,7,0,1,2] [4,5,6,7,0,1,2]
    若旋转 7 次,则可以得到 [ 0 , 1 , 2 , 4 , 5 , 6 , 7 ] [0,1,2,4,5,6,7] [0,1,2,4,5,6,7]
  注意,数组 [ a [ 0 ] , a [ 1 ] , a [ 2 ] , . . . , a [ n − 1 ] ] [a[0], a[1], a[2], ..., a[n-1]] [a[0],a[1],a[2],...,a[n1]] 旋转一次 的结果为数组 [ a [ n − 1 ] , a [ 0 ] , a [ 1 ] , a [ 2 ] , . . . , a [ n − 2 ] ] [a[n-1], a[0], a[1], a[2], ..., a[n-2]] [a[n1],a[0],a[1],a[2],...,a[n2]] 。给你一个元素值 互不相同 的数组 n u m s nums nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
  你必须设计一个时间复杂度为 O(log n)的算法解决此问题。

3.a)题目分析:

  本题需要设计出一个时间复杂度的算法,分治法的专题中的二分法,它的时间复杂度O(log n),所以我们这题就可以使用二分法来解决。

3.b)代码:

class Solution {
    public int findMin(int[] nums) {
        int low = 0;
        int high = nums.length - 1;
        while (low < high) {
            int mid = low + (high - low) / 2;
            if (nums[mid] < nums[high]) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return nums[low];
    }
}

4)70. 爬楼梯

  假设你正在爬楼梯。需要 n n n 阶你才能到达楼顶。每次你可以爬 1 1 1 2 2 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

4.a)题目分析:

  本题为斐波那契数列的应用,可以将第 n n n层分成从第 n − 1 n-1 n1层爬上来和 n − 2 n-2 n2层爬上来,将两次相加即可。

4.b)代码:

class Solution {
    int []a=new int [1000];
    public int climbStairs(int n) {
        a[0]=a[1]=1;
        for(int i=2;i<n+1;i++){
            a[i]=a[i-1]+a[i-2];
        }
        return a[n];
    }
}

5)509. 斐波那契数

  斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
    F(0) = 0,F(1) = 1
    F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n n n,请计算 F ( n ) F(n) F(n)

5.a)题目分析:

  斐波那契数列可以通过 F(n) = F(n - 1) + F(n - 2),其中 n > 1,来表示出来。

5.b)代码:

class Solution {
    public int fib(int n) {
        int []a=new int [1000];
        a[0]=0;
        a[1]=1;
        for(int i=2;i<n+1;i++){
            a[i]=a[i-1]+a[i-2];
        }
        return a[n];
    }
}

6)1137. 第 N 个泰波那契数

  泰波那契序列 T n Tn Tn 定义如下: T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n n n,请返回第 n n n个泰波那契数 T n Tn Tn 的值。

6.a)题目分析:

   泰波那契数是斐波那契数的进阶。

6.b)代码:

class Solution {
    public int tribonacci(int n) {
        int []a=new int [1000];
        a[0]=0;
        a[1]=1;
        a[2]=1;
        for(int i=3;i<n+1;i++){
            a[i]=a[i-1]+a[i-2]+a[i-3];
        }
        return a[n];
    }
}

7)2006. 差的绝对值为 K 的数对数目

  给你一个整数数组 n u m s nums nums 和一个整数 k k k ,请你返回数对 ( i , j ) (i, j) (i,j) 的数目,满足 i < j i < j i<j|nums[i] - nums[j]| == k
   ∣ x ∣ |x| x 的值定义为:
    如果 x > = 0 x >= 0 x>=0 ,那么值为 x x x
    如果 x < 0 x < 0 x<0 ,那么值为 − x -x x

7.a)题目分析:

   本题可以用两层循环,来搜索满足条件的 ( i , j ) (i, j) (i,j),并统计数对的数目。

7.b)代码:

class Solution {
    public int countKDifference(int[] nums, int k) {
        int n =nums.length;
        int ans=0;
        for(int i =0;i<n;i++){
            for(int j =i+1;j<n;j++){
                int s =nums[i]-nums[j];
                    if(s==k||s==-k){
                        ans++;
                    }
            }
        }
        return ans;
    }
}

8)LCP 01. 猜数字

  小 A A A 和 小 B B B 在玩猜数字。小 B B B 每次从 1 , 2 , 3 1, 2, 3 1,2,3 中随机选择一个,小 A A A 每次也从 1 , 2 , 3 1, 2, 3 1,2,3 中选择一个猜。他们一共进行三次这个游戏,请返回 小 A A A 猜对了几次?输入的 g u e s s guess guess数组为 小 A A A 每次的猜测, a n s w e r answer answer数组为 小 B B B 每次的选择。 g u e s s guess guess a n s w e r answer answer的长度都等于 3 3 3

8.a)题目分析:

   本题可以通过同时枚举 g u e s s guess guess数组和 a n s w e r answer answer数组,并进行比较。即可解决问题。

8.b)代码:

class Solution {
    public int game(int[] guess, int[] answer) {
        int n = guess.length;
        int cnt=0;
        for(int i = 0;i<n;i++){
            if(guess[i]==answer[i]){
            cnt++;
            }
        }
        return cnt;
    }
}

9)LCP 06. 拿硬币

  桌上有 n n n 堆力扣币,每堆的数量保存在数组 c o i n s coins coins 中。我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数。

9.a)题目分析:

   本题需要将硬币分成奇数和偶数来计算,如果是偶数,则拿走一堆硬币需要 n / 2 n/2 n/2从;如果是奇数,则需要 n / 2 + 1 n/2+1 n/2+1次。因为是除 2 2 2,所以可以用位运算来解决本题。

9.b)代码:

class Solution {
    public int minCount(int[] coins) {
        int count = 0;
        for(int coin: coins){
            //右移一位相当于除以2,和1按位与相当于除2取余
            count += (coin >> 1) + (coin & 1);
        }
        return count;
    }
}

10)剑指 Offer II 069. 山峰数组的顶部

  符合下列属性的数组 arr 称为 山峰数组(山脉数组) :
   a r r . l e n g t h > = 3 arr.length >= 3 arr.length>=3
    存在 i ( 0 < i < a r r . l e n g t h − 1 ) i(0 < i < arr.length - 1) i0<i<arr.length1使得:
     a r r [ 0 ] < a r r [ 1 ] < . . . a r r [ i − 1 ] < a r r [ i ] arr[0] < arr[1] < ... arr[i-1] < arr[i] arr[0]<arr[1]<...arr[i1]<arr[i]
     a r r [ i ] > a r r [ i + 1 ] > . . . > a r r [ a r r . l e n g t h − 1 ] arr[i] > arr[i+1] > ... > arr[arr.length - 1] arr[i]>arr[i+1]>...>arr[arr.length1]
给定由整数组成的山峰数组 a r r arr arr ,返回任何满足 a r r [ 0 ] < a r r [ 1 ] < . . . a r r [ i − 1 ] < a r r [ i ] > a r r [ i + 1 ] > . . . > a r r [ a r r . l e n g t h − 1 ] arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] arr[0]<arr[1]<...arr[i1]<arr[i]>arr[i+1]>...>arr[arr.length1]的下标 i i i ,即山峰顶部。

10.a)题目分析:

   定义一个整型 m a x max max,遍历数组,将数组中的每一个数与 m a x max max比较,如果比 m a x max max大,则将 a r r [ i ] arr[i] arr[i]赋值给 m a x max max并将下标给 a n s ans ans

10.b)代码:

class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        int n =arr.length;
        int ans =0;
        int max=0;
        for(int i =0;i<n;i++){
            if(max<arr[i]){
                 max=arr[i];
                 ans=i;
            }
        }
        return ans;
    }
}

三、做题记录

在这里插入图片描述

四、今日总结

  今日的题目有需要用动态规划来考虑问题的,动态规划需要找重复、找变化、找边界。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枏念

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值