leetcode第 205 场周赛

  1. 给你一个仅包含小写英文字母和 ‘?’ 字符的字符串 s ,请你将所有的 '?'转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。
    注意:你 不能 修改非 ‘?’ 字符。
    题目测试用例保证 除 '?'字符 之外,不存在连续重复的字符。
    在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。
public String modifyString(String s) {
		if (s == null || s.length() == 0) {
			return s;
		}

		char[] array = s.toCharArray();
		// 满足一种情况就行
		for (int i = 0; i < array.length; i++) {
			if (array[i] == '?') {
				// 取到就跳出
				for (int j = 0; j <= 25; j++) {
					char temp = (char) (j + 'a');
					if ((i + 1) < array.length && temp == array[i + 1]) {
						continue;
					}
					if ((i - 1) >= 0 && temp == array[i - 1]) {
						continue;
					}
					
					array[i] = temp;
					break;
				}
			}
		}

		return new String(array);
	}

2.给你两个整数数组 nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ):
类型 1:三元组 (i, j, k) ,如果 nums1[i]2 == nums2[j] * nums2[k] 其中 0 <= i < nums1.length 且 0 <= j < k < nums2.length
类型 2:三元组 (i, j, k) ,如果 nums2[i]2 == nums1[j] * nums1[k] 其中 0 <= i < nums2.length 且 0 <= j < k < nums1.length

另一种思路:暴力,用hashMap存储nums1的结果,出现次数(nums1[j]*nums1[k]),再遍历nums2(nums2[i]*nums[i]),看hashmap结果集中是否存在,获取出现次数并相加。
tips:注意两int数相乘会出现溢出情况

 // 排序+双指针+组合数
	public int numTriplets(int[] nums1, int[] nums2) {
		if (nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0) {
			return 0;
		}
		Arrays.sort(nums1);
		Arrays.sort(nums2);

		return numTriplets2(nums1, nums2) + numTriplets2(nums2, nums1);
	}

	private int numTriplets2(int[] nums1, int[] nums2) {
		// TODO Auto-generated method stub

		int res = 0;
		for (int i = 0; i < nums1.length; i++) {
			int n = 0;
			int m = nums2.length - 1;
			long sum = (long) nums1[i] * (long) nums1[i];
			// 比最小的还小
			if (sum < (long) nums2[n] * (long) nums2[n]) {
				continue;
			}
			// 比最大的还大
			if (sum > (long) nums2[m] * (long) nums2[m]) {
				break;
			}

			while (n < m) {
				long temp = (long) nums2[n] * (long) nums2[m];
				if (sum > temp) {
					n++;
				} else if (sum < temp) {
					m--;
				} else { // 相同的情况分为两种 1.num2[n] == nums[m] ,就是m-n+1中随机取2个的组合数
					if (nums2[n] == nums2[m]) {
						res += (m - n + 1) * (m - n) / 2;
						break;
					} else {
						// 2.取j,k nums2[n..j]
						// nums2[k..m]中元素相同,即(j-n)*(m-k)的组合数(两边各一个)
						// num2[j-1...k]可能还有存在杰
						int j = n + 1;
						int k = m - 1;
						while (nums2[n] == nums2[j]) {
							j++;
						}
						while (nums2[k] == nums2[m]) {
							k--;
						}
						res += (j - n) * (m - k);
						n = j - 1;
						m = k;
					}

				}
			}
		}

		return res;
	}

3.给你一个字符串 s 和一个整数数组 cost ,其中 cost[i] 是从 s 中删除字符 i 的代价。
返回使字符串任意相邻两个字母不相同的最小删除成本。
请注意,删除一个字符后,删除其他字符的成本不会改变

思路:连续重复的元素中,最大成本的元素保留,其余删除。

public  int minCost(String s, int[] cost) {
		if (s == null || s.length() == 0 || cost == null || cost.length == 0 || cost.length != s.length()) {
			return 0;
		}

		char[] array = s.toCharArray();
		int length = array.length;
		int sum = 0;

		for (int i = 0; i < length; i++) {
			if (i < length - 1 && array[i] == array[i + 1]) {
				// 重复元素只保留最大的
				int max = cost[i];
				char more = array[i];
				do {
					if (max < cost[i]) {
						max = cost[i];
					}
					sum += cost[i];
					i++;
				} while (i < length && array[i] == more);
				sum -= max;
				// 恢复,避免连续++
				i--;
			}
		}

		return sum;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值