目录
- LeetCode 667
- LeetCode 664
- LeetCode 668
- projecteuler 60
- Projecteuler 62
- LeetCode224. 基础计算器
- LeetCode115
- LeetCode 122 & 123
- Projecteuler 77 计算数由质数相加的方法数
- Project 78 基础划分函数取模问题
- Leetcode87 递归子串问题
- Leetcode218 矩形相连求边界点问题
LeetCode 667
题目链接:https://leetcode.com/problems/beautiful-arrangement-ii/description/
题目
给定两个整数n,k,输出一个包含1~n的数组。假定数组是[a1,a2,…,an],保证得到的序列[|a1-a2| , |a2-a3| , … , |an-1 - an|]包含了恰好k个不同的数字。
有多组解的情况下输出任意一组解
1<=k<n<=10000
题解:
这里最重要的是必须使用1~n的所有数字,为了保证能得到1~(n-1)的所有差值,必须左右来回取值保证差值最大,也就是1,n,2,n-1…,取到第k个的位置,因为剩下的数是连续的,那么保证他们的差值都为1即可。
|
|
LeetCode 664
题目链接:https://leetcode.com/problems/strange-printer/description/
题目
有一个奇怪的打印机满足以下两个要求:
1.每次打印一整个连续的序列使其对应位置上打印上同一个字母
2.每次打印可以任意选择起始位置和终点位置,之后的打印会覆盖前面的打印结果
问获得对应字符串需要至少打印多少次\
题解:
利用区间dp的思想,dp[i][j]表示打印好[i,j]的区间至少需要多少次
这里第一层循环是区间的间隔,第二层循环是区间的起始位置,第三个循环是断开的位置,用来将两个区间合并在一起计算
[i,k] [k+1,j]两个区间合并的时候如果s[k] = s[j],那么打印次数可以减一,自己可以画画图看,但是为什么这个可以满足题目所需的所有情况,我还有点困惑需要解决。
|
|
LeetCode 668
题目链接:https://leetcode.com/problems/kth-smallest-number-in-multiplication-table/description/
题目
有一张30000*30000的二维表,每个位置对应的坐标为(x,y),其上的数字是xy的乘积,找到第k小的数字,即将所有数字从小到大排序后出现在第k个位置上的数字。
题解:
二分结果,每次二分根据每一行的数字,找到与之匹配的y的个数即可。
复杂度O(30000*log(30000^2))
|
|
project euler 60
题目链接:https://projecteuler.net/problem=60
题目:
找到5个素数,保证任意两个数字不论先后顺序连接(如11,7,可连接的到117和711)得到的数字都是素数,并保证这五个数字的和最小。
题目已经告诉你在四个素数的情况下是3,7,109,673.
题解:
暂且估计所有数字都不会超过10000,那么素数是1230个左右,那么我们可以将任意两个素数连接判断是否可以组合,可组合就连成一条边,那么最终的结果形成的图,一定是找一个具有5个点的最大团。
|
|
project euler 62
题目链接:https://projecteuler.net/problem=62
题目
找到一个立方数,而且这个立方数的各个数字重新排列位置能得到新的立方数,比如41063625 = 345^3 , 56623104 = 384^3 , 66430123 = 405^3
可以找到三个立方数,最小的是41063625
现在希望让你找到一个重排后产生5个立方数的最小数字
题解:
从结果数字出发太大了,考虑从立方的基数出发,最后产生的结果是不超过10000,实际代码过程中我把限制加到了100000,也依然在3s内运行完成。
将立方数根据0~9出现的个数转化成hash编码后,判断从1^3开始出现的次数,将出现了5次的,找到一个最小值。
|
|
LeetCode224. 基础计算器
题目链接:https://leetcode.com/problems/basic-calculator/description/
题目:
给你一个只包含+ - 运算带括号的字符串,求最后的答案
题解
用栈来存储数据,遇到右括号,一定要将直到第一个左括号这之间的数据计算出来
因为只有加减计算方式有很多种。
我的代码优点小问题在于为了方便我将符号也定义成了数字,单位了区分,我自己随机写的数字,如果计算过程中得到了这些数字,我的程序会将它当成符号来看,只是测试数据中没有遇到,正好就能Accept了。
|
|
LeetCode 115
题目链接:https://leetcode.com/problems/distinct-subsequences/description/
题目
给定两个字符串序列S,T,找到有多少个S的子序列和T相同。
ACE是ABCDE的子序列,但是AEC就不是ABCDE的子序列。
如S =
"rabbbit"
, T ="rabbit"
Return3
题解
一目了然的动态规划思想
f(i , j) 表示S前i个字符和T的前j个字符匹配得到的如问题描述中的方法数
那么状态转移就以第i个位置能否和第j个位置匹配作为标准
因为字符串下标从0开始,所以
f(i+1 , j+1) = f(i , j+1) + s[i] == t[j] ? f(i , j) : 0
当j为0的时候,初始化所有f(i , 0) = 1,其余情况均为0
那么代码就呼之欲出了
|
|
projecteuler 69
题目链接:https://projecteuler.net/problem=69
题目
定义了φ(n)为不大于n的所有和n互质的正整数的数量。
找到1000000以内,令n/φ(n)最大的n值
题解
φ(n)是符合积性函数的性质的
根据积性函数性质在i%pri[j] = 0时,那么φ(i∗pri[j]) = φ(i)∗φ(pri[j])
那么当 i%pri[j] != 0,可以分析得出,φ(i∗pri[j]) = φ(i)∗pri[j]
那么就能根据线性筛法在线性时间复杂度内求解出所有的φ(n)然后作比较即可。
|
|
LeetCode 122 & 123
题目链接:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
问题
给定一个物品价格序列,第i个数字代表第i天物品的价格,你可以通过买进买出来获得收益,保证每一次买进之前要保证当前没有物品或者物品已经卖光的,且一天只能买一个或者卖一个物品。
一次买卖视作一次交易
LeetCode 122 是问可以无限次交易,得到最大收益
LeetCode 123是问最多2次交易,得到最大收益
题解
LeetCode122:
every position has two states :
- sell operation with mark 0
- buy operation with mark 1
dp[i][0] = max(dp[j][1]+price[i])
dp[i][1] = max(dp[j][0]-price[i])
because the current item just influence the last item , so in this recursion , we don’t need array to save optimal value.
mx0 represents the optimal value before with mark 0 ;
mx1 represents the optimal value before with mark 0 ;
mx0 = max(mx0 , mx1+price[i])
mx1 = max(mx1 , mx0-price[i])
|
|
LeetCode123
simple dynamic plan question
same to last question:Best Time to Buy and Sell Stock III
2 transactions at most
Record 4 states
mx[0][0] represent the optimal value of buying stock in first transaction
mx[0][1] represent the optimal value of selling stock in first transaction
mx[1][0] represent the optimal value of buying stock in second transaction
mx[1][1] represent the optimal value of selling stock in second transaction
|
|
Projecteuler 77
Problem link:https://projecteuler.net/problem=77
problem
It is possible to write ten as the sum of primes in exactly five different ways:
7 + 3
5 + 5
5 + 3 + 2
3 + 3 + 2 + 2
2 + 2 + 2 + 2 + 2What is the first value which can be written as the sum of primes in over five thousand different ways?
Method
dynamic plan can solve this question quickly.
In order to repetitive computation, I distinguish the smallest number from other numbers.
for example:
a = b + prime1
a = c + prime2
.
.
.
the ways to constitute a = the ways to constitute b (the smallest prime >= prime1)+ the ways to constitute c(the smallest prime number >= prime2)+ …
ways(i,j)presents how many ways can constitute number i with the smallest prime number pri[j]
the suffix sum of sum(i,j) = ways(i,j)+ways(i,j+1)+ways(i,j+2)+…+ways(i,maxn) is used to lower complexity.
code
Projecteuler 78
题目链接:https://projecteuler.net/problem=78
问题
将正整数n划分成正整数相加的形式的组合,换位置不算不同方法,实际上就是求n的分割函数p(n)。
找到第一个n,使p(n) % 1000000 = 0
题解
对1000000取模,可以在计算划分函数的过程中直接对1000000取模,最后找到n>=2下p(n)=0的第一个数字即可。根据我之前的文章,很容易就写成划分函数的代码。
复杂度O(nsqrt(n))
code
Leetcode 87
题目链接:https://leetcode.com/problems/scramble-string/description/
问题
可以将一个字符串转化成一个二分树,每一个节点生成两个子节点就是将当前节点任选一个位置切分开,不一定要求二分的,这点很重要,开始就是理解错了。
然后判断两个字符串是不是通过交换若干个左右儿子得到的。
题解:
递归处理,只要保证每一个对应子串是一个合理的节点即可,两个子串都在左侧,说明子树没有交换,一个在左一个在右说明子树交换。处理每一个切分位置的正确性,很简单递归处理即可。子树满足条件就是当前子树对应字符串的所有字符个数相同。
|
|
Leetcode218 矩形相连求边界点问题
题目链接:https://leetcode.com/problems/the-skyline-problem/description/
问题
给定所有底在x轴上的矩形,底边两个端点对应在x轴上和矩形的高3个值告诉你可以确定一个矩形。
那么多个矩形覆盖在一起的时候画出除x轴之外的轮廓,找到所有轮廓上每一水平线上最左侧的点集
题解:
一般解决矩形的覆盖问题
最通常的情况都是要区分它的左右侧的边,跟以前做线段树上解决Atlantic求矩形覆盖面积的问题一样。
将左侧边标记为-1,右侧边标记为1,那么所有边由左到右排好序后,左侧边进入容器,右侧边到的时候,将和他等高的左侧边从容器里删除,因为之后的边不再受这个矩形影响了。也就是说容器里所有边的高度都是覆盖了当前对应矩形的范围,那么我们只要判断容器里面的最大高度和自己比较即可。
这里边排序进入容器判断的顺序很关键,我们总是保证在等x的时候,越高的边越优先进入,越低的边越优先出去,这样才不会影响当前容器里最大值的判断。
|
|
且保存这些进入的容器用一个有序的容器可以帮助你最快的找到最大值,我选择的是multiset,因为总是会出现高度一样的边,但我们不能将其相互抵消,所以都应该保存,要注意multiset删除元素一定只删除一个,所以是删除指定的指针,不然相同元素多个,删除值会导致一条右侧边删了多条左侧边。
当然这个问题的解决可以是你自己定义结构体保存在set中,给每一条边定一个id,找到相同id的左侧边删除即可。但这道题目本身不需要这么麻烦就能解决。
|
|