991坏了的计算器
在显示着数字的坏计算器上,我们可以执行以下两种操作:
双倍(Double):将显示屏上的数字乘 2;
递减(Decrement):将显示屏上的数字减 1 。
最初,计算器显示数字 X。
返回显示数字 Y 所需的最小操作数。
逆向思维,Y->X
1. Y为偶数则直接除2,且操作数++
2. Y为奇数则(Y+1)/2,且操作数+=2
3. 循环至Y<X ,操作数+(X-Y)
class Solution {
public int brokenCalc(int x, int y) {
int result = 0;
while(y>x){
if((y&1)==1){
y=(y+1)/2;
result+=2;
}
else {
y/=2;
result++;
}
}
return result+x-y;
}
}
890查找和替换模式
输入:words = [“abc”,“deq”,“mee”,“aqq”,“dkd”,“ccc”], pattern = “abb”
输出:[“mee”,“aqq”]
解释:
“mee” 与模式匹配,因为存在排列 {a -> m, b -> e, …}。
“ccc” 与模式不匹配,因为 {a -> c, b -> c, …} 不是排列。
因为 a 和 b 映射到同一个字母。
将pattern借助hashmap数字化,然后对words进行遍历,同样对word进行数字化,若符合word与pattern则为字符串匹配成功
class Solution {
int [] arrb = null;
int lb;
public boolean isok(String a){
int la = a.length();
if(la!=lb){
return false;
}
int [] arra = new int[la];
int k = 0;
HashMap<Character,Integer> mapa = new HashMap<Character, Integer>();
for(int i = 0;i<arra.length;i++){
Character c = a.charAt(i);
if(mapa.containsKey(c)==false){
k++;
mapa.put(c,k);
arra[i] = k;
}
else arra[i] = mapa.get(c);
}
return Arrays.equals(arra,arrb);
}
public List<String> findAndReplacePattern(String[] words, String pattern) {
List<String> res = new ArrayList<String>();
lb = pattern.length();
arrb = new int[lb];
int k = 0;
HashMap<Character,Integer> mapb = new HashMap<Character, Integer>();
for(int i = 0;i<arrb.length;i++){
Character c = pattern.charAt(i);
if(mapb.containsKey(c)==false){
k++;
arrb[i] = k;
mapb.put(c,k);
}
else arrb[i] = mapb.get(c);
}
mapb.clear();
for (String word:words
) {
if(isok(word)==true){
res.add(word);
}
}
return res;
}
}
567字符串的排列
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).
输入: s1= “ab” s2 = “eidboaoo”
输出: False
数组保存字母出现个数+滑动窗口
注意一些小细节
class Solution {
int[] arra = new int[26];
int[] arrb = new int[26];
public boolean checkInclusion(String s1, String s2) {
int l1 = s1.length();
int l2 = s2.length();
if(l1==0||l2==0||l1>l2){
return false;
}
for(int i = 0;i<l1;i++)
{
arra[s1.charAt(i)-'a']++;
arrb[s2.charAt(i)-'a']++;
}
for(int i = l1;i<=l2;i++){
if(isok())
return true;
arrb[s2.charAt(i-l1)-'a']--;
arrb[s2.charAt(i%l2)-'a']++;
}
return false;
}
public boolean isok() {
for (int i = 0; i < 26; i++) {
if (arra[i] != arrb[i])
return false;
}
return true;
}
}
001两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
#在目标数组内寻找两数和==target
#思路:HashMap存之前数字出现的位置,然后用k2=target-当前数字 去map里找
#注意两数相等的小细节就OK
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
int ans[] = new int[2];
for(int i = 0;i<nums.length;i++){
int k1 =target-nums[i];
int k2 =nums[i] ;
if(map.containsKey(k1)==true){
ans[0] = i;
ans[1] = map.get(k1);
return ans;
}
map.put(k2,i);
}
return ans;
}
}
002两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
#按题意模拟一遍即可,注意一下进位的处理
#ps:可以用递归去做,效率很高
#非递归:
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
List<Integer> la = new ArrayList<Integer>();
List<Integer> lb = new ArrayList<Integer>();
List<Integer> lc = new ArrayList<Integer>();
while(true){
la.add(l1.val);
l1 = l1.next;
if(l1==null){
break;
}
}
while(true){
lb.add(l2.val);
l2 = l2.next;
if(l2==null){
break;
}
}
int lmax = Math.max(la.size(),lb.size());
if(la.size()<lmax){
for(int i = la.size();i<lmax;i++)
{
la.add(0);
}
}
if(lb.size()<lmax){
for(int i = lb.size();i<lmax;i++){
lb.add(0);
}
}
int s=0;
for(int i = 0;i<lmax;i++){
int v1 = la.get(i);
int v2 = lb.get(i);
int v3 = v1+v2+s;
if(v3>=10){
s = 1;
v3-=10;
}
else {
s = 0;
}
lc.add(v3);
}
if(s!=0)
{
lc.add(1);
}
ListNode ans = new ListNode(lc.get(0));
ListNode t ;
t = ans;
for(int i = 1;i<lc.size();i++){
if(t.next==null){
t.next = new ListNode(lc.get(i));
t = t.next;
}
}
return ans;
}
}