Leetcode 161周赛java题解

Leetcode 161周赛java题解

1.交换字符使得字符串相同

有两个长度相同的字符串 s1 和 s2,且它们其中 只含有 字符 “x” 和 “y”,你需要通过「交换字符」的方式使这两个字符串相同。

每次「交换字符」的时候,你都可以在两个字符串中各选一个字符进行交换。

交换只能发生在两个不同的字符串之间,绝对不能发生在同一个字符串内部。也就是说,我们可以交换 s1[i] 和 s2[j],但不能交换 s1[i] 和 s1[j]。

最后,请你返回使 s1 和 s2 相同的最小交换次数,如果没有方法能够使得这两个字符串相同,则返回 -1 。
示例 1:

输入:s1 = “xx”, s2 = “yy”
输出:1
解释:
交换 s1[0] 和 s2[1],得到 s1 = “yx”,s2 = “yx”。
示例 2:

输入:s1 = “xy”, s2 = “yx”
输出:2
解释:
交换 s1[0] 和 s2[0],得到 s1 = “yy”,s2 = “xx” 。
交换 s1[0] 和 s2[1],得到 s1 = “xy”,s2 = “xy” 。
注意,你不能交换 s1[0] 和 s1[1] 使得 s1 变成 “yx”,因为我们只能交换属于两个不同字符串的字符。
示例 3:
输入:s1 = “xx”, s2 = “xy”
输出:-1
示例 4:
输入:s1 = “xxyyxyxyxx”, s2 = “xyyxyxxxyx”
输出:4
提示:
1 <= s1.length, s2.length <= 1000
s1, s2 只包含 ‘x’ 或 ‘y’。
思路:好像是个codeforce前几天的A题,先判断xy的个数是否为偶数,然后统计
X Y和Y X的对数mod2。如果对数是奇数的话再加2.

	  public int minimumSwap(String s1, String s2) {
			 	        int count =-1;char c1[]=s1.toCharArray();char[]c2=s2.toCharArray();
			 	        int counta=0,countb=0;
			 	        for(int i=0;i<s1.length();i++) {
			 	        	if(c1[i]=='x') {
			 	        		counta++;
			 	        	}else {
			 	        		countb++;
			 	        	}	
			 	        	if(c2[i]=='x') {
			 	        		counta++;
			 	        	}else {
			 	        		countb++;
			 	        	}
			 	        }int count3=0,countc=0,countd=0;
			 	        if(counta%2!=0||countb%2!=0) {
			 	        	return -1;
			 	        }else { 
			 	        	for(int i=0;i<c1.length;i++) {
			 	        		if(c1[i]=='x'&&c2[i]=='y') {
			 	        			countc++;
			 	        		}
			 	        		if(c1[i]=='y'&&c2[i]=='x') {
			 	        			countd++;
			 	        		}
			 	        	}count3 =(countc/2)+(countd/2);
	                      //  System.out.println(countc+" "+countd);
			 	        	if(countc%2==1) {
			 	        		count3+=2;
			 	        	}
			 	        }
			 	    	return count3;
			 	    } 

2.统计「优美子数组」 显示英文描述

给你一个整数数组 nums 和一个整数 k。

如果某个子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。

请返回这个数组中「优美子数组」的数目。

思路:统计奇数与奇数间隔,计算第i个间隔+1与第i+k个间隔+1的和即为所求
例 [1,1,2,1,1]的间隔为 0 0 1 0 0
计算(arr[0]+1)(arr[3+1)+(arr[1]+1)(arr[4]+1)即可

 public int numberOfSubarrays(int[] nums, int k) {
		 	        int count =0;
		 	        for(int i=0;i<nums.length;i++) {
		 	        	if(nums[i]%2==1) {
		 	        		count++;
		 	        	}
		 	        }
		 	        if(nums.length<k) {
		 	        	return 0;
		 	        }else {
		 	        	int i=0;int []arr=new int[count+1];
		 	        	int cou=0;int j=0;
		 	        	while(i<nums.length) {
		 	        		if(nums[i]%2==0) {
		 	        			cou++;
		 	        		}else {
		 	        			arr[j]=cou;
		 	        			j++;
		 	        			cou=0;
		 	        		}
		 	        		if(i==nums.length-1) {
		 	        			arr[j]=cou;
                                break;
		 	        		}
		 	        		i++;
		 	        	}
		 	        //	System.out.println(Arrays.toString(arr));
		 	        	int sum=0;
		 	        	for(int s=0;s<arr.length-k;s++) {
		 	        	sum+=(arr[s]+1)*(arr[s+k]+1);
		 	        	}
		 	        	return sum;
		 	        }
		 	       
		 	    }

3.5249. 移除无效的括号

给你一个由 ‘(’、’)’ 和小写字母组成的字符串 s。

你需要从字符串中删除最少数目的 ‘(’ 或者 ‘)’ (可以删除任意位置的括号),使得剩下的「括号字符串」有效。

请返回任意一个合法字符串。

有效「括号字符串」应当符合以下 任意一条 要求:

空字符串或只包含小写字母的字符串
可以被写作 AB(A 连接 B)的字符串,其中 A 和 B 都是有效「括号字符串」
可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」
思路 :一个栈存括号的角标,一个栈存括号,并实时往map中更新不合理的括号,最后遍历将不合理的位置山区即可。

 public String minRemoveToMakeValid(String s) {
			 	    char c[]=s.toCharArray();
			 	    Stack<Integer>stack2=new Stack<>();

			 	    Map<Integer,Integer>map=new HashMap<>();
			 	    Stack<String>stack=new Stack<>();
			 	    int ji=-1;
		 	    for(int i=0;i<c.length;i++) {
		 	    	if(c[i]=='(') {
		 	    		stack.add("(");
		 	    		stack2.add(i);
		 	    		map.put(i, 1);
		 	    	}
		 	    	else if(c[i]==')'&&stack.size()!=0) {
		 	    		map.remove(stack2.peek());
		 	    		stack2.pop();
		 	    		stack.pop();
		 	    	}else if(c[i]==')') {
		 	    		map.put(i, 2);
		 	    	}
		 	    }StringBuilder sb=new StringBuilder();
		 	    for(int i=0;i<s.length();i++) {
		 	    	if(c[i]=='('||c[i]==')') {
		 	    		if(map.containsKey(i)) {
		 	    			continue;
		 	    		}else {
		 	    			sb.append(s.substring(i, i+1));
		 	    		}
		 	    	}else {
		 	    		
		 	    		sb.append(s.substring(i, i+1));
		 	    	}
		 	    }
		 			 return sb.toString();   
		 	    } 
}

4.5250. 检查「好数组」 显示英文描述

给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。

假如该和结果为 1,那么原数组就是一个「好数组」,则返回 True;否则请返回 False。
思路:只需判断n个数的最大公约数是不是1即可。
一方面如果n个数最大公约数大于1,那么如果k是最大公约数,k整除于1,矛盾
另一方面不会证 猜的

public static int Gcd(int a,int b)
						{
						            if (0 == b) return a;
						            else return Gcd(b, a % b);
						}
			 		public static  int GcdN(int[] digits,int length)
			 		{
			 		            if (1 == length) return digits[0];
			 		            else return Gcd(digits[length - 1], GcdN(digits, length - 1));
			 		}
			 		 public boolean isGoodArray(int[] nums) {
			 	        if(GcdN(nums,nums.length)==1) {
			 	        	return true;
			 	        }else {
			 	        	return false;
			 	        }
			 	    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值