LeetCode周期小结12-03

7. 整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

输入: 123
输出: 321

示例 2:

输入: -123
输出: -321

示例 3:

输入: 120
输出: 21

注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

我的解答

public static int reverse(int x) {
		//判断是否溢出
		if(x<Integer.MAX_VALUE&&x>Integer.MIN_VALUE) {
			//转化为字符串,进行进一步操作 
			String str = x+"";
			String newStr ="";
			//判断是否为负数
			if(x<0) {
				str = str.substring(1, str.length());
				newStr = dofun(str);
				newStr = "-"+newStr;
			}else {
				newStr = dofun(str);
			}
			//转换回整形
			//判断反转后是否超出范围
			double test = Double.parseDouble(newStr);
			if(test>Integer.MAX_VALUE||test<Integer.MIN_VALUE) {
				return 0;
			}
			int result = Integer.parseInt(newStr);
			return result;
		}
		return 0;
    }

	public static String dofun(String str) {
		String newStr = "";
		//置换
		for(int i=str.length();i>0;i--) {
			newStr += str.charAt(i-1);
		}
		//判断最高位是否为0
		while(newStr.charAt(0)==0) {
			//是,无视该位
			newStr = newStr.substring(1, str.length());
		}
		return newStr;
	}

更优解答

 public int reverse(int x) {
	        int rev = 0;
	        while (x != 0) {
	            int pop = x % 10;
	            x /= 10;
	            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
	            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
	            rev = rev * 10 + pop;
	        }
	        return rev;
	    }

196. 删除重复的电子邮箱
编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。

| Id | Email
| 1 | john@example.com
| 2 | bob@example.com
| 3 | john@example.com

Id 是这个表的主键。

例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:
| Id | Email
| 1 | john@example.com
| 2 | bob@example.com

我的解答

DELETE p2 FROM Person p1, Person p2 WHERE p1.Email=p2.Email AND p1.id<p2.id

349. 两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]

说明:

输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。

我的解答

class Solution {
   	public static int[] intersection(int[] nums1, int[] nums2) {

		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < nums1.length; i++) {
			for (int j = 0; j < nums2.length; j++) {
				if (nums1[i] == nums2[j]) {
					list.add(nums1[i]);
				}
			}
		}
		
		//根据需求决定去重
		list = removeRepeat(list);
		
		int[] result = new int[list.size()];
		for (int k = 0; k < list.size(); k++) {
			result[k] = list.get(k);
		}
		
		
		return result;
	}
	
	//去重
	public static List<Integer> removeRepeat(List<Integer> list) {
		List<Integer> listNew=new ArrayList<>();
		for (Integer str:list) {
            if(!listNew.contains(str)){
                listNew.add(str);
            }
        }
		return listNew;
	}
}

更优解答

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
       Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        
        for (int num : nums1) {
            set1.add(num);
        }
        
        for (int num : nums2) {
            if (set1.contains(num)) {
                set2.add(num);
            }
        }
        
        int[] ret = new int[set2.size()];
        int i = 0;
        for (int num : set2) {
            ret[i++] = num;
        }
        return ret;
    }
}

14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

示例 1:

输入: [“flower”,“flow”,“flight”]
输出: “fl”

示例 2:

输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。

说明:

所有输入只包含小写字母 a-z 。

我的解答

public static String longestCommonPrefix(String[] strs) {
		if (strs == null || strs.length == 0) return "";
		//由于最后采用substring方法,所以这里先指定一个字符串用于表示结果
		String result = strs[0];
		for (int i = 0; i < strs.length; i++) {
			int j = 0;
			for (j = 0; j < result.length(); j++) {
				if (result.charAt(j) != strs[i].charAt(j))
					break;
			}
			result = result.substring(0, j);
		}
		return result;
	}

更优解答

class Solution {
    public String longestCommonPrefix(String[] strs){ if(strs == null || strs.length==0)  return ""; 
    String prifex = strs[0]; // 默认将第一个认为是最长共同
        for(int i=1;i<strs.length;i++){ // 将当前最长共同字符串和当前数组中的对比,把小的那个作为长度
            int len = prifex.length()>strs[i].length() ? strs[i].length():prifex.length(); 
            int j=0;
             for(j=0;j<len;j++){ // 逐个字符比较,不等的时候退出
                if(prifex.charAt(j)!=strs[i].charAt(j))
                 break; 
                 } // 退出的j即当前的最小,整个遍历结束后就是整个的最小了
            prifex = prifex.substring(0,j);
             } 
             return prifex;
              }
}

26. 删除排序数组中的重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。

我的解答

public int removeDuplicates(int[] nums) {
	    if (nums.length == 0) return 0;
	    int i = 0;
	    for (int j = 1; j < nums.length; j++) {
	        if (nums[j] != nums[i]) {
	            i++;
	            nums[i] = nums[j];
	        }
	    }
	    return i + 1;
	}

更优解答 (速度更快)

class Solution {
    public int removeDuplicates(int[] nums) {
       if(nums ==  null || nums.length == 0){
			return 0;
		}
		
		//1、标记重复数据
		final int mark = nums[0];
		int index = 1 , _index =1,num =0;
		while(index<nums.length){
			_index = index;
			while(++_index<nums.length && nums[_index]!= mark && nums[index] == nums[_index]){
				nums[_index] = mark;
			}
			index ++;
		}
		
		index = _index = 1;
		while (_index <nums.length && index <nums.length) {
			while (_index<nums.length && nums[_index]==mark) {
				num++;
				_index++;
			}
			if(_index<nums.length){
				nums[index]=nums[_index];
				_index++;
			}
			index++;
		}
		return nums.length-num;
    }
}

20. 有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: “()”
输出: true

示例 2:

输入: “()[]{}”
输出: true

示例 3:

输入: “(]”
输出: false

示例 4:

输入: “([)]”
输出: false

示例 5:

输入: “{[]}”
输出: true

我的代码

public static boolean isValid2(String s) {
	//排除项数是奇数的情况
        if(s.length()%2!=0)
         return false;
       
        int count = 0;
        int length = s.length();
        while(count<length/2){
            s = s.replace("{}","").replace("[]","").replace("()","");
            System.out.println(s);
            count++;
        }
        if(s.length()>0){
             return false;
        }
        else{
             return true;
        }
    }

更优解答

	class Solution {
		public boolean isValid(String s) {
			Stack<Character> stack = new Stack<Character>();
			for (char c : s.toCharArray()) {
				if (c == '(')
					stack.push(')');
				else if (c == '[')
					stack.push(']');
				else if (c == '{')
					stack.push('}');
				else if (stack.isEmpty() || stack.pop() != c)
					return false;
			}
			return stack.isEmpty();
		}
	}

495. 提莫攻击
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。

你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。

示例1:

输入: [1,4], 2
输出: 4
原因: 在第 1 秒开始时,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持 2 秒钟,直到第 2 秒钟结束。
在第 4 秒开始时,提莫再次攻击艾希,使得艾希获得另外 2 秒的中毒时间。
所以最终输出 4 秒。

示例2:

输入: [1,2], 2
输出: 3
原因: 在第 1 秒开始时,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持 2 秒钟,直到第 2 秒钟结束。
但是在第 2 秒开始时,提莫再次攻击了已经处于中毒状态的艾希。
由于中毒状态不可叠加,提莫在第 2 秒开始时的这次攻击会在第 3 秒钟结束。
所以最终输出 3。

我的解答

class Solution {
	 public static int findPoisonedDuration(int[] timeSeries, int duration) {
           if(timeSeries.length==0)  return 0;
		 
		 //中毒时间
		 int poisoning = 0;
		 
		 for(int i=0;i<timeSeries.length-1;i++) {
			 //gap表示时间点小于duration的情况
			 int gap = timeSeries[i+1]-timeSeries[i];
			 if(gap>=duration) {
				 poisoning += duration;
			 }else {
				 poisoning += gap;
			 }
		 }
		 //提莫最后一次攻击后的中毒时间
		 poisoning += duration;
		 return poisoning;
	 }
}

更优解答

class Solution {
 
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        
        if (timeSeries.length == 0) {
            return 0;
        }
        int res = 0;
        int startTime = timeSeries[0];
        for (int i = 1; i < timeSeries.length; ++i) {
            int preEndTime = timeSeries[i - 1] + duration;
            if (timeSeries[i] >= preEndTime) {
                res += preEndTime - startTime;
                startTime = timeSeries[i];
            }
        }
        res += timeSeries[timeSeries.length - 1] + duration - startTime;
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值