LeetCode算法题完成计划(二)

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;
    }
}

 

你可能感兴趣的:(LeetCode算法题完成计划(二))