刷题-DAY9

题目一

一上来就是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);
	}	

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值