暑期2022.08算法讲解

题目 LeetCode15
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

解题思路
思路1:暴力求解,3 层循环。时间复杂度 O(nnn)
思路2:2 层循环,第 1 层循环遍历数组,作为 target,第二层循环参考两数求和的逻辑。

思路3:先排序后查找,时间复杂度 O(n*n)

class Solution {
        public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList();
        int len = nums.length;
        if(nums == null || len < 3) return list;
        Arrays.sort(nums); // 排序
        for (int i = 0; i < len ; i++) {
            if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
            if(i > 0 && nums[i] == nums[i-1]) continue; // 则说明该数字重复,会导致结果重复,所以应该跳过
            int L = i+1;//指针从第二个数开始移动
            int R = len-1;
            while(L < R){
                int sum = nums[i] + nums[L] + nums[R];
                if(sum == 0){
                    list.add(Arrays.asList(nums[i],nums[L],nums[R]));
                    while (L<R && nums[L] == nums[L+1]) L++; // 则会导致结果重复,应该跳过
                    while (L<R && nums[R] == nums[R-1]) R--; // 则会导致结果重复,应该跳过
                    L++;
                    R--;
                }
                else if (sum < 0) L++;
                else if (sum > 0) R--;
            }
        }
        return list;
    }
}

求数组的第K小数字 

求数组的第k小,数字数量非常多。

Input

每组数据给出n m k表示有n个数,求第k小,数组的数字由以下规则得到:

ai = mi mod  (109+7), i = 1, 2, ..., n

其中 1 ≤ n, m ≤ 5 × 107, 1 ≤ k ≤ n,数据保证得到的数组元素大部分互不相等。

Output

输出第k小的数

Sample Input

3 2 2

Sample Output

4

Hint

先复习下快速排序的实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<cmath>
#include<complex>
#include<vector>
#include<algorithm>
const int mod = 1e9 + 7;
const int maxn = 1e8 + 10;
int n, m, k;
int a[maxn];
int GetK(int left, int right, int k)
{
    if(left == right - 1) return a[left];
    int low = left, high = right - 1, center = a[low];
    while(low < high)
    {
        while(low < high && a[high] >= center) high --;
        a[low] = a[high];
        while(low < high && a[low] <= center) low ++;
        a[high] = a[low];
    }
    a[low] = center;
    if(low - left >= k) return GetK(left, low, k);
    else if(low - left + 1 == k) return a[low];
    else return GetK(low + 1, right, k - (low - left) - 1);
}
int main()
{
    while(scanf("%d%d%d", &n, &m, &k) != EOF)
    {
        a[0] = m;
        for(int i = 1; i < n; i ++)
            a[i] = 1LL * a[i - 1] * m % mod;
        printf("%d\n", GetK(0, n, k));
    }
    return 0;
}


3题目:

给你一个混合字符串 s ,请你返回 s 中 第二大 的数字,如果不存在第二大的数字,请你返回 -1 。

混合字符串 由小写英文字母和数字组成。

示例 1:

输入:s = "dfa12321afd"
输出:2
解释:出现在 s 中的数字包括 [1, 2, 3] 。第二大的数字是 2 。
示例 2:

输入:s = "abc1111"
输出:-1
解释:出现在 s 中的数字只包含 [1] 。没有第二大的数字。

提示:

1 <= s.length <= 500
s 只包含小写英文字母和(或)数字。

思路:

此题比较简单,直接遍历,用两个变量记录第1大和第2大的数即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HehuaTang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值