1、平方数之和
给定一个非负整数 c
,你要判断是否存在两个整数 a
和 b
,使得 a2 + b2 = c。
分析:可以用双指针法来解决,时间复杂度是O(n)
class Solution {
public boolean judgeSquareSum(int c) {
int left = 0,right = (int)Math.sqrt(c);
while (left<=right){
if(left*left+right*right>c){
right--;
}else if(left*left+right*right
2、两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
分析:可以先用set过滤数组中相同的元素,然后再遍历其中一个数组
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set result = new HashSet<>();
Set num = new HashSet<>();
for(int n :nums1){
num.add(n);
}
for(int n:nums2){
if(num.contains(n))
result.add(n);
}
int[] r = new int[result.size()];
int i =0;
for(int temp:result){
r[i++]=temp;
}
return r;
}
}
3、第三大的数
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
分析:可以暴力破解,先找出第一大的数,再找第二大的数,再找第三大的数,时间复杂度也是O(n)
class Solution {
public int thirdMax(int[] nums) {
if(nums.length==1)
return nums[0];
else if(nums.length==2){
return nums[0]>nums[1]?nums[0]:nums[1];
}else {
int third = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
int first = Integer.MIN_VALUE;
int count = 0;
boolean f=true;
for(int n :nums){
if(n==Integer.MIN_VALUE&&f){
count++;
f=false;
}
if(n>first){
count++;
third = second;
second = first;
first = n;
}else if(n>second&&nthird&&n=3?third:first;
}
}
}
4、等价多米诺骨牌对的数量
给你一个由一些多米诺骨牌组成的列表 dominoes。
如果其中某一张多米诺骨牌可以通过旋转 0 度或 180 度得到另一张多米诺骨牌,我们就认为这两张牌是等价的。
形式上,dominoes[i] = [a, b] 和 dominoes[j] = [c, d] 等价的前提是 a==c 且 b==d,或是 a==d 且 b==c。
在 0 <= i < j < dominoes.length 的前提下,找出满足 dominoes[i] 和 dominoes[j] 等价的骨牌对 (i, j) 的数量。
分析:可以用哈希表来存储数对,存储时数对按照小-大来存储,以免重复
class Solution {
public int numEquivDominoPairs(int[][] dominoes) {
int count =0;
Map map = new HashMap<>();
for (int[] dominoe : dominoes) {
int min = dominoe[0]>dominoe[1]?dominoe[1]:dominoe[0];
int max = dominoe[0]>dominoe[1]?dominoe[0]:dominoe[1];
String key = min+"-"+max;
if(map.containsKey(key)){
map.put(key,map.get(key)+1);
}else {
map.put(key,1);
}
}
for(Integer integer :map.values()){
if(integer>1){
count += integer*(integer-1)/2;
}
}
return count;
}
}
5、亲密字符串
给定两个由小写字母构成的字符串 A
和 B
,只要我们可以通过交换 A
中的两个字母得到与 B
相等的结果,就返回 true
;否则返回 false
。
分析:如果A和B不相等的话,可以先让A和B的值一起进行异或运算,如果为0,且同一个下标的值进行异或运算,不为0的放入set中,如果set的长度为2,返回真,如果A和B相等的话,只要A中有重复的值,返回真
class Solution {
public boolean buddyStrings(String A, String B) {
char result = 0;
if(!A.equals(B)){
if(A.length()!=B.length())
return false;
Set aSet = new HashSet<>();
Set bSet = new HashSet<>();
for(int i = 0;i map = new HashMap<>();
for(Character character:A.toCharArray()){
if(map.containsKey(character)){
map.put(character,map.get(character)+1);
}else {
map.put(character,1);
}
}
for(Integer i :map.values()){
if(i>1)
return true;
}
return false;
}
}
}
6、长按键入
你的朋友正在使用键盘输入他的名字 name。偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次。
你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回 True。
class Solution {
public boolean isLongPressedName(String name, String typed) {
if(name.length()>typed.length())
return false;
StringBuilder sName = new StringBuilder();
StringBuilder sType = new StringBuilder();
char n = name.charAt(0),t = typed.charAt(0);
for(Character c :name.toCharArray()){
if(c!=n){
sName.append('-');
n = c;
}
sName.append(c);
}
for(Character c:typed.toCharArray()){
if(c!=t){
t = c;
sType.append('-');
}
sType.append(c);
}
String[] names = sName.toString().split("-");
String[] types = sType.toString().split("-");
if(names.length>types.length)
return false;
for(int i =0;itypes[i].length())
return false;
}
return true;
}
}
7、赎金信
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。)
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(ransomNote.length()>magazine.length())
return false;
Map map = new HashMap<>();
for(Character c :magazine.toCharArray()){
if(map.containsKey(c)){
map.put(c,map.get(c)+1);
}else {
map.put(c,1);
}
}
for(Character c:ransomNote.toCharArray()){
if(map.containsKey(c)){
if(map.get(c)==0)
return false;
else {
map.put(c,map.get(c)-1);
}
}else {
return false;
}
}
return true;
}
}
8、旋转数字
我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。要求每位数字都要被旋转。
如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。0, 1, 和 8 被旋转后仍然是它们自己;2 和 5 可以互相旋转成对方;6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。
现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?
class Solution {
public int rotatedDigits(int N) {
int ans = 0;
for (int i = 1;i <= N;i++) {
if (judge(i)) {
ans++;
}
}
return ans;
}
private boolean judge(int num) {
String rule = "0182569";
boolean ok = false;
while (num != 0) {
int m = num % 10;
if (rule.indexOf((char) (m + '0')) < 0) {
return false;
}
if (m == 2 || m == 5 || m == 6 || m == 9) {
ok = true;
}
num /= 10;
}
return ok;
}
}
9、
机器人能否返回原点
在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。
移动顺序由字符串表示。字符 move[i] 表示其第 i 次移动。机器人的有效动作有 R(右),L(左),U(上)和 D(下)。如果机器人在完成所有动作后返回原点,则返回 true。否则,返回 false。
注意:机器人“面朝”的方向无关紧要。 “R” 将始终使机器人向右移动一次,“L” 将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。
class Solution {
public boolean judgeCircle(String moves) {
int[] result = new int[]{0,0};
for(char c :moves.toCharArray()){
switch (c){
case 'L':result[0]+=1;
break;
case 'R':result[0]-=1;
break;
case 'U':result[1]+=1;
break;
case 'D':result[1]-=1;
break;
default:
break;
}
}
return result[0]==0&&result[1]==0;
}
}
10、唯一摩尔斯密码词
国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 "-...", "c" 对应 "-.-.", 等等。
为了方便,所有26个英文字母对应摩尔斯密码表如下:
[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
class Solution {
public int uniqueMorseRepresentations(String[] words) {
String[] morse = new String[]{".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
Map map = new HashMap<>();
char a = 'a';
for(String str:morse){
map.put(a,str);
a = (char)(a+1);
}
Set set = new HashSet<>();
for(String word :words){
StringBuilder s = new StringBuilder();
for(char c :word.toCharArray()){
s.append(map.get(c));
}
set.add(s.toString());
}
return set.size();
}
}
11、字符串中的单词数
统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。
请注意,你可以假定字符串里不包括任何不可打印的字符。
class Solution {
public int countSegments(String s) {
int count = 0;
String[] strs = s.split(" ");
for(String str :strs){
if(!str.trim().equals(""))
count++;
}
return count;
}
}
12、数组中的K-diff数对
给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k.
class Solution {
public int findPairs(int[] nums, int k) {
if(k<0)
return 0;
int count = 0;
Set set = new HashSet<>();
if(k==0){
Map map = new HashMap<>();
for(int num:nums){
if(map.containsKey(num)){
map.put(num,map.get(num)+1);
}else {
map.put(num,1);
}
}
for(int num :map.values()){
if(num>1)
count++;
}
return count;
}
for(int num :nums){
set.add(num);
}
Set reSet = new HashSet<>();
for(Integer num :set){
if(set.contains(num+k)&&!reSet.contains(num)){
count++;
reSet.add(num);
}
}
return count;
}
}
13、最常见的单词
给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。题目保证至少有一个词不在禁用列表中,而且答案唯一。
禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。
class Solution {
public String mostCommonWord(String paragraph, String[] banned) {
Set set = new HashSet<>();
Collections.addAll(set, banned);
paragraph = paragraph.replace('!',' ');
paragraph = paragraph.replace('?',' ');
paragraph = paragraph.replace('\'',' ');
paragraph = paragraph.replace(',',' ');
paragraph = paragraph.replace(';',' ');
paragraph = paragraph.replace('.',' ');
paragraph = paragraph.toLowerCase();
String[] p = paragraph.split(" ");
Map map = new HashMap<>();
String result = "";
int max=0;
for(String str :p){
if(!str.trim().equals("")){
if(map.containsKey(str)){
map.put(str,map.get(str)+1);
}else {
map.put(str,1);
}
}
}
for(String str :map.keySet()){
if(map.get(str)>max&&(!set.contains(str))){
result = str;
max = map.get(str);
}
}
return result;
}
}
14、猜数字大小
我们正在玩一个猜数字游戏。 游戏规则如下:
我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。
每次你猜错了,我会告诉你这个数字是大了还是小了。
你调用一个预先定义好的接口 guess(int num),它会返回 3 个可能的结果(-1,1 或 0):
-1 : 我的数字比较小
1 : 我的数字比较大
0 : 恭喜!你猜对了!
/* The guess API is defined in the parent class GuessGame.
@param num, your guess
@return -1 if my number is lower, 1 if my number is higher, otherwise return 0
int guess(int num); */
public class Solution extends GuessGame {
public int guessNumber(int n) {
int left = 1,right = n,mid = left +(right-left)/2;
while (guess(mid)!=0){
if(guess(mid)==1){
left = mid+1;
}else {
right = mid-1;
}
mid = left+(right-left)/2;
}
return mid;
}
}
15、错误的集合
集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。
给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
class Solution {
public int[] findErrorNums(int[] nums) {
int[] result = new int[2];
Set set = new HashSet<>();
int sum = 0;
for(int i = 0;i
16、单词规律
给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。
这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。
class Solution {
public boolean wordPattern(String pattern, String str) {
String[] strings = str.split(" ");
for(String s:strings){
System.out.println(s);
}
if(strings.length!=pattern.length())
return false;
Map map = new HashMap<>();
for(int i =0;i
17、七进制数
给定一个整数,将其转化为7进制,并以字符串形式输出。
class Solution {
public String convertToBase7(int num) {
int n = num;
num = num>=0?num:-num;
StringBuilder s = new StringBuilder();
while(num/7!=0){
s.append(num%7);
num/=7;
}
s.append(num);
StringBuilder result = new StringBuilder();
for(int i=s.toString().length()-1;i>=0;--i){
result.append(s.charAt(i));
}
return n>=0?result.toString():"-"+result.toString();
}
}
18、转换成小写字母
实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。
class Solution {
public String toLowerCase(String str) {
StringBuilder s = new StringBuilder();
for(int i=0;i='A'&&str.charAt(i)<='Z'){
s.append((char)(str.charAt(i)+'a'-'A'));
}else {
s.append(str.charAt(i));
}
}
return s.toString();
}
}
19、有序数组的平方
给定一个按非递减顺序排序的整数数组 A
,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
class Solution {
public int[] sortedSquares(int[] A) {
int []B = new int[A.length];
int i = 0, j = A.length-1, k = B.length-1;
while(i<=j){
if(Math.abs(A[i])>Math.abs(A[j]))
B[k--] = A[i]*A[i++];
else
B[k--] = A[j]*A[j--];
}
return B;
}
}
20、检测大写字母
给定一个单词,你需要判断单词的大写使用是否正确。
我们定义,在以下情况时,单词的大写用法是正确的:
全部字母都是大写,比如"USA"。
单词中所有字母都不是大写,比如"leetcode"。
如果单词不只含有一个字母,只有首字母大写, 比如 "Google"。
否则,我们定义这个单词没有正确使用大写字母。
分析:从第二个字母开始检查,如果是大写字母,则全为大写字母,如果是小写字母,则后面为小写字母
class Solution {
public boolean detectCapitalUse(String word) {
if(word.length()<=1)
return true;
if(word.charAt(1)<='Z'&&word.charAt(1)>='A'){//第2个是大写
for(int i = 0;i='a')
return false;
}
}else {//第二个是小写
for(int i = 1;i='A')
return false;
}
}
return true;
}
}