题目一
一上来就是hard 信封问题
给你一个二维整数数组 envelopes
,其中 envelopes[i] = [wi, hi]
,表示第 i
个信封的宽度和高度。
当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
注意:不允许旋转信封。
先说结论 先按长从小到大排 然后宽从大到小排 然后以排序后的宽生成一个数组 在数组里面找最长子递增序列
逻辑是 先把长从小到大排 这个好理解吧 小的才能套进长的里面
然后宽从大到小排说明啥 在同样的长的情况下 是从大到小 这里面的大肯定套不进小的里面 因为长必须严格小于另一个信封才能塞里面 但是我们要求递增子序列 如果递增了 就说明肯定不是同一个长度了 而且按照长从小到大 只能长越来越大 所以长度肯定解决 宽呢?宽也要求有小到大(我们就要求的递增子序列) 所以在一个递增子序列的信封数组中 前面的肯定比后面的小 就一定能放在后面的里面
lass Node{
int w;
int h;
public Node(int w,int h) {
this.w = w;
this.h = h;
}
}
class Mycompare implements Comparator<Node>{
@Override
public int compare(Node o1,Node o2) {
return o1.w==o2.w?o2.h-o1.h:o1.w-o2.w;
}
}
class Solution {
public static int getpos (int [] arr, int cur,int last) {
for(int i = last;i>=0;i--) {
if(arr[i]<cur) {
return i;
}
}
return -1;
}
public int maxEnvelopes(int[][] envelopes) {
Node [] nodes = new Node [envelopes.length];
for(int i = 0;i<envelopes.length;i++) {
nodes[i] = new Node(envelopes[i][0], envelopes[i][1]);
}
Arrays.sort(nodes, new Mycompare());
int [] dp = new int [nodes.length];
int [] ends = new int [nodes.length];
int last = 0;
int max = 1;
ends[0] = nodes[0].h;
dp[0] = 1;
for(int i = 0;i<nodes.length;i++) {
if(nodes[i].h>ends[last]) {
ends[++last] = nodes[i].h;
dp[i] = last+1;
}else {
int pos = getpos(ends,nodes[i].h,last)+1;
ends[pos] = nodes[i].h;
}
max = Math.max(max, dp[i]);
}
return max;
}
}
题目二
奶牛问题
刚开始有一只母牛 然后母牛每年生一头小母牛 小母牛三年能参与生产 问N年后有多少母牛
看一下这篇博客
斐波那契数列问题
public static int mymethod(int n) {
if (n < 1) {
return 0;
}
if (n == 1 || n == 2 || n == 3) {
return n;
}
int[][] base = {
{ 1, 1, 0 },
{ 0, 0, 1 },
{ 1, 0, 0 } };
int[][] res = matrixPower(base, n - 3);
return 3 * res[0][0] + 2 * res[1][0] + res[2][0];
}
public static int[][] mymatrixPower(int [][] base,int N){
int [][] res = new int[base.length][base[0].length];
for(int i = 0;i<base[0].length;i++) {
res[i][i] = 1;
}
int [][] tmp = base;
for(;N!=0;N>>=1) {
if((N&1)!=0) {
res = mymuliMatrix(res,tmp);
}
tmp = mymuliMatrix(tmp,tmp);
}
return res;
}
public static int[][] mymuliMatrix(int[][] m1, int[][] m2) {
int [][] res = new int [m1.length][m2[0].length];
for(int i = 0;i<m1.length;i++) {
for(int j = 0;j<m2[0].length;j++) {
for (int k = 0; k < m2.length; k++) {
res[i][j] += m1[i][k] * m2[k][j];
}
}
}
return res;
}
题目三
啊 来一道简单点的
给一个数组 有两个数出现了奇数次 其他数都出现了偶数次
对于有一个数出现奇数次 很好解对吧 根据异或的性质 当相同的值相异或 结果为0 不同异或结果为1 (对于二进制来说)所以把它异或在一起 就可以了
那两个数呢? 还是把它们都异或在一起 偶数个数的东西都互相消掉了 只剩a^b(两个出现奇数的数字) 那他们也就是说 他们异或的结果 必定有一位是1(二进制) 而且这位上 他们一定是不同的
所以我们接着异或所有数 来一个if判断 如果这个位置上是1 那么我们就不要这个数 就能把这个数排除出去了(那如果我把其他的不该排除出去的数排除了怎么办? 没事啊 对于另一个出现奇数次的数 它当前位肯定为0 至于其他出现偶数个的数 要不他们异或也会为0 排除出去也不影响结果)
然后最后 异或出来的结果 就是其中一个出现奇数次数的数 然后再用之前a^b的结果^b 也就是a^b^b 求出a
public static void getnum(int [] arr) {
int eor = 0;
for(int i = 0;i<arr.length;i++) {
eor^=arr[i];
}
int rightone = eor&(~eor+1);
int one = 0;
for(int i = 0;i<arr.length;i++) {
if((arr[i]&rightone)!=0)
one^=arr[i];
}
int two = eor^one;
System.out.println(one+" "+two);
}