LC560. 和为 K 的子数组
//首先第一时间想到的就是双循环来进行算取求和并且count计算子数组个数。
//迭代遍历
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0;
for (int start = 0; start < nums.length; ++start) {
int sum = 0;
for (int end = start; end >= 0; --end) {
sum += nums[end];
if (sum == k) {
count++;
}
}
}
return count;
}
}
//前缀和 + 哈希表记忆化搜索,通过空间换时间
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0;
//key,前缀和pre,value为个数
HashMap<Integer,Integer> map = new HashMap();
int pre = 0;
//有可能存在当前数就是k,也记录从下标0开始到i之和为k的情况
map.put(0,1);
for(int i = 0;i < nums.length;i++){
pre += nums[i];
if(map.containsKey(pre - k)){
count += map.get(pre - k);
}
map.put(pre,map.getOrDefault(pre,0) + 1);
}
return count;
}
}
LC47. 全排列 II
//因为是全排列所以不许用在递归函数上面传入一个变量去控制循环的起始下标,当然因为要返回不重复的排列数,那么我们可以定义一个booolean的数组下标放入递归函数当中传给下一个函数去查看如果当前用过了设置为true。那么在循环当中如果当前used为true就可以跳过,
class Solution {
private List<List<Integer>> res = new ArrayList();
private LinkedList<Integer> item = new LinkedList();
private int[] used;
public List<List<Integer>> permute(int[] nums) {
if(nums.length == 0)
return res;
used = new int[nums.length];
dfs(nums,0);
return res;
}
public void dfs(int[] nums,int n){
if(n == nums.length)
//不能是res.add(item),这只会是一个引用依然会回退元素然后形成一个空数组
//那么我们需要一个快照的形式,也就是要一个值,res.add(new ArryaList(item))
res.add(new ArrayList(item));
for(int i = 0;i < nums.length;i++){
if(used[i] == 0){
item.add(nums[i]);
used[i] = 1;
dfs(nums,n + 1);
used[i] = 0;
item.removeLast();
}
}
}
}
LC189. 轮转数组
//之前做过类似的题目是轮转链表,将链表成环,找到转移点的前一个位置,设置头节点后,切点链表。返回头节点即可。在数组当中发现一个规律将数字整体反转,然后以k作为区间切割,[0, k - 1] [k,nums.length - 1]。反转这两个区间过后就是答案
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums,0,nums.length - 1);
reverse(nums,0,k - 1);
reverse(nums,k,nums.length - 1);
}
public void reverse(int[] nums,int start,int end){
while(start < end){
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}