1.一维数组动态和:自己做出来了
给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。
请返回 nums 的动态和。
解题思路:我是用的双重for循环来做,赋值到一个新的数组,官方给的方法是用++对原数组进行循环
//我的思路:
class Solution {
public int[] runningSum(int[] nums) {
int[] sum = new int[nums.length];
for(int i=0;i<nums.length;i++)
{
if(i==0)
{
sum[i]=nums[i];
}
else
{
for(int j=0;j<=i;j++)
{
sum[i]=sum[i]+nums[j];
}
}
}
return sum;
}
}
//官方思路:
class Solution {
public int[] runningSum(int[] nums) {
int n = nums.length;
for (int i = 1; i < n; i++) {
nums[i] += nums[i - 1];//这句循环++的操作是核心
}
return nums;
}
}
/* 作者:LeetCode-Solution
链接:https://leetcode.cn/problems/running-sum-of-1d-array/solution/yi-wei-shu-zu-de-dong-tai-he-by-leetcode-flkm/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
2.不同整数的最少数目:
给你一个整数数组 arr 和一个整数 k 。现需要从数组中恰好移除 k 个元素,请找出移除后数组中不同整数的最少数目。
解题思路:先把每个整数出现的次数和整数放入一个map表中,然后重要的是对map表进行排序,这样才在删除时先删除出现次数少的,留下不同整数的最少数目,考察Map,List排序
//官方思路:
class Solution {
public int findLeastNumOfUniqueInts(int[] arr, int k) {
Map<Integer, Integer> group = new HashMap<>();
for (int num : arr) {
int count = group.getOrDefault(num, 0) + 1;
group.put(num, count);
}
List<int[]> freq = new ArrayList<>();
/**
* 这个
*/
for (Map.Entry<Integer, Integer> entry : group.entrySet()) {
int[] keyValue = {entry.getKey(), entry.getValue()};
freq.add(keyValue);
}
freq.sort(Comparator.comparingInt(keyValue -> keyValue[1]));
//下面这段代码的排序我看不懂,用idea改成上面的就容易看明白了,可能下面的return还是返回按照[1]排序,可能是这样.
/*Collections.sort(freq, new Comparator<int[]>() {
public int compare(int[] keyValue1, int[] keyValue2) {
return keyValue1[1] - keyValue2[1];
}
});*/
int ans = freq.size();
for (int[] ints : freq) {
int occ = ints[1];
if (k >= occ) {
--ans;
k -= occ;
} else {
break;
}
}
return ans;
}
}
3.正则表达式匹配:这道题目还没看懂,要多研究—动态规划+状态转移
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
解题思路:动态规划,*+前面的字母可以视为空,那么就可以匹配(i=?j-2)来判断t/f利用状态转移表格来做,每个位置有一个初始状态,然后写出每个位置的后续状态,看最后一个状态是T/F.
//官方思路:
class Solution {
public boolean isMatch(String s, String p) {
int m = s.length();
int n = p.length();
boolean[][] f = new boolean[m + 1][n + 1];//这个布尔数组要大一点,因为0行0列需要空值
f[0][0] = true;
for (int i = 0; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (p.charAt(j - 1) == '*') {
f[i][j] = f[i][j - 2];//每个位置的状态由前一个位置的状态决定
if (matches(s, p, i, j - 1)) {
f[i][j] = f[i][j] || f[i - 1][j];
}
} else {
if (matches(s, p, i, j)) {
f[i][j] = f[i - 1][j - 1];
}
}
}
}
return f[m][n];
}
public boolean matches(String s, String p, int i, int j) {
if (i == 0) {
return false;
}
if (p.charAt(j - 1) == '.') {
return true;
}
return s.charAt(i - 1) == p.charAt(j - 1);
}
}
4.装水最多的容器:
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
解题思路:我写了一个穷举法,结果超时了,妈的,官方的好方法是双指针,从两头开始找,这样找更快速,并且使用了Math.max函数,使运行更快.
//官方思路:
class Solution {
public int maxArea(int[] height) {
int l = 0, r = height.length - 1;
int ans = 0;
while (l < r) {
int area = Math.min(height[l], height[r]) * (r - l);
ans = Math.max(ans, area);
if (height[l] <= height[r]) {
++l;
}
else {
--r;
}
}
return ans;
}
}
5.错误的集合:默认后面一个相同的是出错的数
集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。
给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
解题思路:先对数组进行排序,然后遍历数组,类似1,2,2,4,则先把后面2放入err[0],然后遍历到4,4-2>1,则err[1]=2+1=3,类似1,3,3,4,则先找到3-1>1,err[1]=1+1=2,再找到第二个3,放入err[0]中.
//官方思路:
class Solution {
public int[] findErrorNums(int[] nums) {
int[] errorNums = new int[2];
int n = nums.length;
Arrays.sort(nums);
int prev = 0;
for (int i = 0; i < n; i++) {
int curr = nums[i];
if (curr == prev) {
errorNums[0] = prev;
} else if (curr - prev > 1) {
errorNums[1] = prev + 1;
}
prev = curr;
}
//最后一位出错,就这样处理
if (nums[n - 1] != n) {
errorNums[1] = n;
}
//Array.sort(errorNums);这个不需要,因为默认err[1]放的是原来的数.
return errorNums;
}
}
本文记录了在LeetCode上解决的几道经典算法题,包括一维数组动态和、不同整数的最少数目、正则表达式匹配、装水最多的容器以及错误的集合问题。解题思路涉及双重循环、Map排序、动态规划和状态转移等方法,对提升算法能力有一定帮助。
931

被折叠的 条评论
为什么被折叠?



