前一段时间比较忙,而且做这个对于我来说挺耗时间的,已经间隔了几期的没做总结了,后面有机会补齐。而且本来做这个的目的就是为了防止长时间不做把编程拉下,不在追求独立作出所有题了。以后完赛后稍微尝试下,做不出来的直接放弃。

第一题:问题

问题:900. RLE 迭代器

编写一个遍历游程编码序列的迭代器。

迭代器由 RLEIterator(int[] A) 初始化,其中 A 是某个序列的游程编码。更具体地,对于所有偶数iA[i] 告诉我们在序列中重复非负整数值 A[i + 1] 的次数。

迭代器支持一个函数:next(int n),它耗尽接下来的  n 个元素(n >= 1)并返回以这种方式耗去的最后一个元素。如果没有剩余的元素可供耗尽,则  next 返回 -1 。

例如,我们以 A = [3,8,0,9,2,5] 开始,这是序列 [8,8,8,5,5] 的游程编码。这是因为该序列可以读作 “三个零,零个九,两个五”。

示例:

输入:["RLEIterator","next","next","next","next"], [[[3,8,0,9,2,5]],[2],[1],[1],[2]]
输出:[null,8,8,5,-1]
解释:
RLEIterator 由 RLEIterator([3,8,0,9,2,5]) 初始化。
这映射到序列 [8,8,8,5,5]。
然后调用 RLEIterator.next 4次。 .next(2) 耗去序列的 2 个项,返回 8。现在剩下的序列是 [8, 5, 5]。 .next(1) 耗去序列的 1 个项,返回 8。现在剩下的序列是 [5, 5]。 .next(1) 耗去序列的 1 个项,返回 5。现在剩下的序列是 [5]。 .next(2) 耗去序列的 2 个项,返回 -1。 这是由于第一个被耗去的项是 5,
但第二个项并不存在。由于最后一个要耗去的项不存在,我们返回 -1。

提示:

  1. 0 <= A.length <= 1000
  2. A.length 是偶数。
  3. 0 <= A[i] <= 10^9
  4. 每个测试用例最多调用 1000 次 RLEIterator.next(int n)
  5. 每次调用 RLEIterator.next(int n) 都有 1 <= n <= 10^9 。

链接:https://leetcode-cn.com/contest/weekly-contest-101/problems/rle-iterator/

分析:

看到例子没怎么想,直接试图构建原始数据,然后next更新下标,根据下标直接返回,结果测试中数据很大,懒惰,想当然了。

最终做法是将原始数据建立坐标和值的映射关系,一个data数组,一个index数组(其实就相当于map),然后有变量记录下标,下标值大于index值后,更新到下一个,如果在其范围内,返回对应的数字。

比如例子给出的数据,处理后是:

3 8

5 5

表示坐标3一下的对应值是8,5一下的对应值是5。

AC Code:

class RLEIterator {
public:
vector<long long> datas; //保存数据
vector<long long> sizes; //保存坐标
long long location; //数组坐标
long long datalocation; //当前数字坐标
long long size; //总个数
int endflag; //一旦某个坐标返回-1,后面next都返回-1,做一个优化
public:
RLEIterator(vector<int> A)
{
this->location = 0;
this->datalocation = 0;
this->size = 0;
this->endflag = 0; for (int i = 0; i < A.size(); i+=2)
{
this->size += A[i];
if (A[i] == 0)
{
continue;
}
if (i == 0)
{
this->sizes.emplace_back(A[i]);
}
else
{
this->sizes.emplace_back(A[i] + this->sizes[this->sizes.size()-1]);
} this->datas.emplace_back(A[i+1]);
} } int next(int n)
{
if (this->endflag == 1)
{
return -1;
}
if (this->datalocation + n>=this->size)
{
this->endflag = 1;
return -1;
}
this->datalocation += n; while (this->datalocation > this->sizes[this->location])
{
this->location += 1;
}
return this->datas[this->location];
}
};

其他:

1.第一code

class RLEIterator {
int[] a;
int p = ; public RLEIterator(int[] A) {
a = A;
p = ;
} public int next(int n) {
if(p >= a.length)return -;
n--;
int ret = -;
while(n > ){
if(p >= a.length)return -;
int ex = Math.min(a[p], n);
n -= ex;
a[p] -= ex;
if(a[p] > ){
break;
}else{
p += ;
}
}
while(p < a.length && a[p] == )p += ;
if(p < a.length)ret = a[p+];
n = ; while(n > ){
if(p >= a.length)return -;
int ex = Math.min(a[p], n);
n -= ex;
a[p] -= ex;
if(n == )break;
p += ;
}
return ret;
}
}

2.中间有遇到一个问题,思路什么都多,提交错误,然后调试发现数据范围int是不够的。

第二题:901. 股票价格跨度

问题:

编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度。

今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天)。

例如,如果未来7天股票的价格是 [100, 80, 60, 70, 60, 75, 85],那么股票跨度将是 [1, 1, 1, 2, 1, 4, 6]

示例:

输入:["StockSpanner","next","next","next","next","next","next","next"], [[],[100],[80],[60],[70],[60],[75],[85]]
输出:[null,1,1,1,2,1,4,6]
解释:
首先,初始化 S = StockSpanner(),然后:
S.next(100) 被调用并返回 1,
S.next(80) 被调用并返回 1,
S.next(60) 被调用并返回 1,
S.next(70) 被调用并返回 2,
S.next(60) 被调用并返回 1,
S.next(75) 被调用并返回 4,
S.next(85) 被调用并返回 6。 注意 (例如) S.next(75) 返回 4,因为截至今天的最后 4 个价格
(包括今天的价格 75) 小于或等于今天的价格。

提示:

  1. 调用 StockSpanner.next(int price) 时,将有 1 <= price <= 10^5
  2. 每个测试用例最多可以调用  10000 次 StockSpanner.next
  3. 在所有测试用例中,最多调用 150000 次 StockSpanner.next
  4. 此问题的总时间限制减少了 50%。

链接:https://leetcode-cn.com/contest/weekly-contest-101/problems/online-stock-span/

分析:

如果前一天的股票不大于今天的股票,就可以将其添加的今天的上面,然后将前一天的边界处再次进行判断。

如给出的例子中,

1 2 3 4 5 6 7
100 80 60 70 60 75 85

第一天100,最大连续天数1

第二天80,小于昨天,最大连续天数1

第三条60,小于昨天,最大连续天数1

第四天70,大于昨天,最大连续天数为1+昨天的连续天数1=2,同时查看前一天的80,大于70,第四天最大连续天数2

第五天60,小于昨天,最大连续天数1

第六天75,大于昨天,加上昨天的连续天数1+1,同时查看边界,即第四天,70<75,加上第四天的连续长度2,查看这一天的边界,即第二天,80>75,则最终最大连续天数为1+1+2=4

第七天85,大于昨天,最大连续天数1+4,查看前一天的边界,即第2天,80<85,加上改天的长度1,查看对比边界100>85,最终连续长度1+4+1=6

AC Code:

class StockSpanner {
public:
private:
vector<long long> datas;
vector<long long> longest;
public:
StockSpanner()
{ } int next(int price)
{
if (this->datas.size() == )
{
//diyici
this->datas.emplace_back(price);
this->longest.emplace_back();
return ;
}
else
{
this->datas.emplace_back(price);
if (this->datas[this->datas.size() - ] > price)
{
this->longest.emplace_back();
return ;
}
else
{ int localindex = this->longest.size()-;
int ret = +this->longest[localindex];
localindex -= this->longest[localindex];
while (localindex>= && price>= this->datas[localindex])
{
ret += this->longest[localindex];
localindex -= this->longest[localindex];
}
this->longest.emplace_back(ret);
return ret; } }
}
};

其他:

1.第一code

class StockSpanner {
int[] stack;
int[] value;
int sp;
int gen = ; public StockSpanner() {
stack = new int[];
value = new int[];
sp = ;
gen = ;
} public int next(int price) {
while(sp > && value[sp-] <= price){
sp--;
}
int ret = gen - (sp == ? - : stack[sp-]);
stack[sp] = gen++;
value[sp] = price;
sp++;
return ret;
}
}

第三题:最大为 N 的数字组合

问题:

我们有一组排序的数字 D,它是  {'1','2','3','4','5','6','7','8','9'} 的非空子集。(请注意,'0'不包括在内。)

现在,我们用这些数字进行组合写数字,想用多少次就用多少次。例如 D = {'1','3','5'},我们可以写出像 '13', '551', '1351315' 这样的数字。

返回可以用 D 中的数字写出的小于或等于 N 的正整数的数目。

示例 1:

输入:D = ["1","3","5","7"], N = 100
输出:20
解释:
可写出的 20 个数字是:
1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77.

示例 2:

输入:D = ["1","4","9"], N = 1000000000
输出:29523
解释:
我们可以写 3 个一位数字,9 个两位数字,27 个三位数字,
81 个四位数字,243 个五位数字,729 个六位数字,
2187 个七位数字,6561 个八位数字和 19683 个九位数字。
总共,可以使用D中的数字写出 29523 个整数。

提示:

  1. D 是按排序顺序的数字 '1'-'9' 的子集。
  2. 1 <= N <= 10^9

链接:https://leetcode-cn.com/contest/weekly-contest-101/problems/numbers-at-most-n-given-digit-set/

分析:

1.如果数字位数低于目标数字,肯定满足要求

2.如果位数相同,如果首位小于目标数字最高位,则剩下数字可以随意组合

通用的,如果最高位数字、次高位数字相同,剩下的位数可以随意组合,如此递归直到数字完全相同。

3.n个数字,组成m位数字,有n^m种组发。

AC Code:

class Solution {
public: int atMostNGivenDigitSet(vector<string>& D, int N)
{
//先组成所有的数字,然后挑选满足条件的结果
//首先拿到N的位数length,从D中挑选任意数字累计重复length次,得到所有可能的数字
//大小为D.size^length,太多了,需要优化
//关键是位数相同的一个,低于的位数可以直接计算指数,位数低一定满足
//更关键的是最高位, long long ret = ;
vector<int> datas;
for (long long i = ; i < D.size(); i++)
{
datas.emplace_back(D[i][] - '');
}
if (GetLength(N) == )
{
return GetLessOrEqlN(datas, N).size();
}
long long num1 = GetSameLengthNums(datas, N);
long long num2 = GetLowLengthNums(datas.size(), N / );
ret = num1 + num2;
return ret;
}
long long GetLowLengthNums(int size, int N)
{
long long length = GetLength(N);
if (size == ) //1个数字组成任何位数数字都只有1种组发
{
return length;
}
long long ret = ;
while (length>)
{
ret += (int)pow(size, length);
length--;
}
return ret;
}
long long GetSameLengthNums(vector<int> datas, int N)
{
long long ret = ; while (N)
{
if (N < )
{
ret += GetLessOrEqlN(datas, N).size(); //如果是10以下的数字,直接找到所有不大于该数的个数即可
break;
}
int length = GetLength(N);
int num = N / ((int)pow(, length-));
ret += GetLessN(datas, num).size()*(int)pow(datas.size(), length-);
int findflag = ; //如果高位有相同的,还需要对比次高位,直到拼出相等数字
for (int i = ; i < datas.size(); i++)
{
int tmp = datas[i] - num;
if (tmp==)
{
findflag = ;
break;
}
}
if (findflag == )
{
//cout << "no target,break" << endl;
break;
}
N %= ((int)pow(, length - ));
if (GetLength(N) + != length)
{
break;
}
} return ret;
}
vector<int> GetLessN(vector<int> org, int n)
{
vector<int> ret;
for (int i = ; i < org.size(); i++)
{
if (org[i] < n)
{
ret.emplace_back(org[i]);
}
}
return ret;
}
vector<int> GetLessOrEqlN(vector<int> org, int n)
{
vector<int> ret;
for (int i = ; i < org.size(); i++)
{
if (org[i] <= n)
{
ret.emplace_back(org[i]);
}
}
return ret;
}
int GetLength(int N)
{
int ret = ;
while (N)
{
ret++;
N /= ;
}
return ret;
}
};

其他:

1.第一code

    class Solution {
public int atMostNGivenDigitSet(String[] D, int N) {
int mask = ;
for(String s : D){
mask ^= <<s.charAt()-'';
}
char[] s = Integer.toString(N+).toCharArray();
long dp = ;
int e = ;
for(int i = ;i < s.length;i++){
dp *= Integer.bitCount(mask); for(int j = ;j < s[i]-'';j++){
if(mask<<~j<){
dp+=e;
}
}
if(i > ){
dp += Integer.bitCount(mask);
}
if(mask<<~(s[i]-'')>=){
e = ;
}
}
return (int)dp;
}
}

直接将N+1,避免了==的额外处理,这个思路非常好。

2.手残将复制写作==,折腾了半天才发现,单步调试直接优化跳过了,还以为数据类型问题导致不能直接对比。

3.做的时候大体code完成之后简单测试通过,提价错误,解决提交,又有错误,再次解决,感觉在不停的在打补丁,一方面说明思路不完整,没能直接覆盖到所有情况,另一方面进一步暴露出测试数据设计上的不足,之前就有发现这个问题,不过感觉没多少提高,实际上在周赛的时候一般只是测试下例子,基本没有构造数据测试,关键是没时间,其次能力不足,难以短时间构建出合理的数据。好在编写的测试函数能够将所有的测试用例都保存下,一旦修改code可以将之前测过的所有数据测一遍,避免解决一个问题导致前面的测例failed。

第四题:DI 序列的有效排列

问题:

我们给出 S,一个源于 {'D', 'I'} 的长度为 n 的字符串 。(这些字母代表 “减少” 和 “增加”。)
有效排列 是对整数 {0, 1, ..., n} 的一个排列 P[0], P[1], ..., P[n],使得对所有的 i

  • 如果 S[i] == 'D',那么 P[i] > P[i+1],以及;
  • 如果 S[i] == 'I',那么 P[i] < P[i+1]

有多少个有效排列?因为答案可能很大,所以请返回你的答案模 10^9 + 7.

示例:

输入:"DID"
输出:5
解释:
(0, 1, 2, 3) 的五个有效排列是:
(1, 0, 3, 2)
(2, 0, 3, 1)
(2, 1, 3, 0)
(3, 0, 2, 1)
(3, 1, 2, 0)

提示:

  1. 1 <= S.length <= 200
  2. S 仅由集合 {'D', 'I'} 中的字符组成。

链接:https://leetcode-cn.com/contest/weekly-contest-101/problems/valid-permutations-for-di-sequence/

分析:

这种大数据类型一直都很头疼,放弃不折腾了

AC Code:

其他:

第一code

class Solution {
public int numPermsDISequence(String S) {
int n = S.length();
int[] a = new int[n+];
int p = ;
int len = ;
for(int i = ;i < n;i++){
if(S.charAt(i) == 'D'){
len++;
}else{
a[p++] = len+;
len = ;
}
}
a[p++] = len+; int mod = ;
long[][] C = new long[ + ][ + ];
for (int i = ; i <= ; i++) {
C[i][] = ;
for (int j = ; j <= i; j++) {
C[i][j] = C[i - ][j - ] + C[i - ][j];
if (C[i][j] >= mod)
C[i][j] -= mod;
}
} a = Arrays.copyOf(a, p);
long[] dp = new long[p+];
dp[] = ;
int all = ;
for(int i = ;i <= p;i++){
all += a[i-];
int s = ;
for(int j = i-, sgn = ;j >= ;j--, sgn = -sgn){
s += a[j];
dp[i] += dp[j] * C[all][s] * sgn;
dp[i] %= mod;
}
if(dp[i] < )dp[i] += mod;
}
return (int)dp[p];
}
}
检举作弊

总结:

TI8那一次没参加周赛,其他的几次都参加了,但是总结没做,有的是有完成四道题,有的还没做完,还有一个有写到草稿箱,第四个没完成所以没发布。工作了,有很多事情要做,很难专注算法的提高与练习,而且本身天赋有限,有些问题如果想搞懂需要花太多的时间与精力,虽说当初开始的目的就是增长见识,性格使然还是一直在尽量做出所有问题,努力追求完美,结果更不完美。以后要逐渐学会放弃,不管做到什么程度,尽量周二晚前完成总结。

学习不易,坚持更难,继续努力吧。

LeetCode之Weekly Contest 101的更多相关文章

  1. LeetCode之Weekly Contest 102

    第一题:905. 按奇偶校验排序数组 问题: 给定一个非负整数数组 A,返回一个由 A 的所有偶数元素组成的数组,后面跟 A 的所有奇数元素. 你可以返回满足此条件的任何数组作为答案. 示例: 输入: ...

  2. LeetCode之Weekly Contest 92

    第一题:转置矩阵 问题: 给定一个矩阵 A, 返回 A 的转置矩阵. 矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引. 示例 1: 输入:[[1,2,3],[4,5,6],[7,8,9] ...

  3. LeetCode之Weekly Contest 93

    第一题:二进制间距 问题: 给定一个正整数 N,找到并返回 N 的二进制表示中两个连续的 1 之间的最长距离. 如果没有两个连续的 1,返回 0 . 示例 1: 输入:22 输出:2 解释: 22 的 ...

  4. LeetCode之Weekly Contest 91

    第一题:柠檬水找零 问题: 在柠檬水摊上,每一杯柠檬水的售价为 5 美元. 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯. 每位顾客只买一杯柠檬水,然后向你付 5 美元.10  ...

  5. LeetCode之Weekly Contest 90

    LeetCode第90场周赛记录 第一题:亲密字符串 问题: 给定两个由小写字母构成的字符串 A 和 B ,只要我们可以通过交换 A 中的两个字母得到与 B 相等的结果,就返回 true :否则返回  ...

  6. LeetCode Weekly Contest 8

    LeetCode Weekly Contest 8 415. Add Strings User Accepted: 765 User Tried: 822 Total Accepted: 789 To ...

  7. Leetcode Weekly Contest 86

    Weekly Contest 86 A:840. 矩阵中的幻方 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个 ...

  8. leetcode weekly contest 43

    leetcode weekly contest 43 leetcode649. Dota2 Senate leetcode649.Dota2 Senate 思路: 模拟规则round by round ...

  9. LeetCode Weekly Contest 23

    LeetCode Weekly Contest 23 1. Reverse String II Given a string and an integer k, you need to reverse ...

随机推荐

  1. SQL Server权限设置

    常用的几个系统表:(其实是View) sysdatabases,主数据库,服务器上的数据库 sysobjects,每个数据库,所有数据库对象 syscolumns,每个数据库,列 sysprocess ...

  2. CC13:回文链表

    题目 请编写一个函数,检查链表是否为回文. 给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文. 测试样例: {1,2,3,2,1} 返回:true {1,2,3,2, ...

  3. [LOJ 2190] 「SHOI2014」信号增幅仪

    [LOJ 2190] 「SHOI2014」信号增幅仪 链接 链接 题解 坐标系直到 \(x\) 轴与椭圆长轴平行 点的坐标变换用旋转公式就可以了 因为是椭圆,所以所有点横坐标除以 \(p\) 然后最小 ...

  4. jetty jndi数据源

    applicationContext.xml <?xml version="1.0" encoding="utf-8"?> <beans de ...

  5. MapReduce编程入门实例之WordCount:分别在Eclipse和Hadoop集群上运行

    上一篇博文如何在Eclipse下搭建Hadoop开发环境,今天给大家介绍一下如何分别分别在Eclipse和Hadoop集群上运行我们的MapReduce程序! 1. 在Eclipse环境下运行MapR ...

  6. JAVA基础之基本类型包装类、System类、Math类、Arrays类及大数据运算

    个人理解: 为了方便运算及调用一些方法,我们需要将基本类型的数值转换为对象:不过转换的时候需要特别注意好它们的类型到底是什么,需要调用方法的类名是哪个!特别注意是Byte常量池的相关问题(==):gc ...

  7. Spring Cloud--搭建Eureka注册中心服务

    使用RestTemplate远程调用服务的弊端: Eureka注册中心: Eureka原理: 搭建Eureka服务 引pom 启动类: 启动类上要加上@EnableEurekaServer注解: 配置 ...

  8. Java的API及Object类、String类、字符串缓冲区

    Java 的API 1.1定义 API: Application(应用) Programming(程序) Interface(接口) Java API就是JDK中提供给开发者使用的类,这些类将底层的代 ...

  9. Xiaocms 去版权

    Xiaocms 去版权 后台去版权: 1.  登录页面 修改文件:\admin\template\login.tpl.php 代码: <td width="190" rows ...

  10. Seven Deadly Sins: Gluttony, Greed, Sloth, Wrath, Pride, Lust, and Envy.

    Seven Deadly Sins: Gluttony, Greed, Sloth, Wrath, Pride, Lust, and Envy.七宗罪:暴食.贪婪.懒惰.暴怒.傲慢.色欲.妒忌.