1、两个数组间的距离值(leetcode1385)
两重for循环,外层枚举arr1的元素,二层枚举arr2的元素,设置一个amount值来记录不符合条件的arr1元素数量,最后返回arr1的长度 - amount的数值。
class Solution {
public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
int x = arr1.length, y = arr2.length,amount = 0 ;//amount不符合条件的元素个数
for(int i = 0 ; i < x ; i ++ )
{
for(int j = 0 ; j < y ; j ++)if(Math.abs(arr1[i] - arr2[j]) <= d)
{
amount++;
break;
}
}
return x - amount;
}
}
2、顺次数(leetcode1291)
我们可以发现相同位数的顺次数之间是相差多个1的,比如123和234是相差111,4567和5678也是相差1111。所以我们可以先计算出基于low位数的最小顺次数(比如low是455,那么三位数的最小顺次数就是123),然后循环加对应位数的1,判断是否属于low和high的范围。还有一个判断条件就是如果顺位数的个位为0的话,就要将顺位数的位数加一位,比如原本是789,加了111后就变成790,就不符合了,要将它变成1234.
class Solution {
public List<Integer> sequentialDigits(int low, int high) {
//template表示12345的开头,template2表示11111的加数
int low_ex = low, template = 0, template2 =0,k = 1;
List<Integer> li = new ArrayList<>();
//计算基于low和high的最小顺次数和连续1的加数
while(low_ex != 0)
{
template = template * 10 + k;
template2 = template2 * 10 + 1;
k ++;
low_ex /= 10;
}
int i = template;
//遍历基于low和high之间的顺次数
while(i <= high)
{
if(i % 10 == 0)
{
template = template * 10 + k;
k ++;
i = template;
template2 = template2 * 10 + 1;
continue;
}
else if(low <= i && i <= high)li.add(i);
i += template2;
}
return li;
}
}
3、下一个更大的数值平衡数(2048)
可以使用HashMap统计大于n的每个数中出现的数字,如果是HashMap[i] == i , 就是平衡数,第一个出现的就是结果。
class Solution {
public int nextBeautifulNumber(int n) {
Map<Integer,Integer> map;
for(int i = n ; ;i ++ )
{
int template = i ;
map = new HashMap<>();
while(template != 0)
{
if(!map.containsKey(template % 10))map.put(template % 10 , 1);
else
{
int num = map.get(template % 10);
map.put(template % 10 , ++num);
}
template /= 10;
}
template = i;
while (template != 0)
{
if(map.get(template % 10) != template % 10)break;
template /= 10;
}
if(template == 0)
{
if(i > n)return i;
}
}
}
}
4、两个数组的交集(leetcode349)
这题可以利用HashSet来分别统计两个数组的数字,然后以其中长度较短的HashSet为标准去判断另一个HashMap的交集。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
for(int i : nums1)
{
set1.add(i);
}
for(int i : nums2)
{
set2.add(i);
}
List<Integer> li = new ArrayList<>();
if(set1.size() >= set2.size())
{
Iterator<Integer> iterator = set2.iterator();
while(iterator.hasNext())
{
int num = iterator.next();
if(set1.contains(num))li.add(num);
}
}
else
{
Iterator<Integer> iterator = set1.iterator();
while(iterator.hasNext())
{
int num = iterator.next();
if(set2.contains(num))li.add(num);
}
}
int []result = new int[li.size()];
for(int i = 0 ; i < result.length ; i ++ )result[i] = li.get(i);
return result;
}
}
5、统计特殊四元组(leetcode1995)
这题使用了英雄哥开篇介绍的哈希降维方法。
class Solution {
public int countQuadruplets(int[] nums) {
Map<Integer , Integer> map = new HashMap<>();
int amount = 0;
for(int c = 0 ; c < nums.length ; c ++)
{
for(int b = 0 ; b < c ; b ++)
{
for(int a = 0 ; a < b ; a ++)
{
if(!map.containsKey(nums[a] + nums[b]))map.put(nums[a] + nums[b] , 1);
else
{
int num = map.get(nums[a] + nums[b]);
map.put(nums[a] + nums[b],++num);
}
}
}
for(int d = c + 1 ; d < nums.length ; d ++)
{
if(map.containsKey(nums[d] - nums[c]))
{
amount += map.get(nums[d] - nums[c]);
}
}
map.clear();
}
return amount;
}
}
6、两个数组的交集(leetcode1566)
思路就是它要匹配连续的重复子序列,那么数组中就一定有k * m长度的一段是以模式重复的,比如使1 2重复3次,那么数组中就要有一段是121212,所以只需要找到这一段就好了。
从arr数组头i = 0开始遍历,设置一个loc的值用来记录重复子序列的下标(也就是121212的下标),接着判断arr[i +loc] == arr[i + loc % m] ,如果相等就loc++,继续往下,如果不相等就i++,然后继续从loc=0开始。那么为什么要loc % m呢?因为是长度为m的子序列(比如1 2,长度为2)重复k(3)次(即1 2 1 2 1 2),(假设当前loc为 4)loc % m(4 % 2 ) 得到 0 就可以定位到 下标为0,即数字 1,用来判断与loc[i + loc]是否相等。
class Solution {
public boolean containsPattern(int[] arr, int m, int k) {
//要匹配的长度
int tem_len = m * k , loc = 0;
for(int i = 0 ; i + tem_len <= arr.length ; i ++)
{
for(loc = 0 ; loc < tem_len ; loc ++)
{
//取余是为了定位到模式串中
if(arr[i + loc] != arr[i + loc % m])break;
}
if(loc == m * k)return true;
}
return false;
}
}