LeetCode 335. 路径交叉 / 260. 只出现一次的数字 III / 500. 键盘行

335. 路径交叉

2021.10.29 每日一题

题目描述

给你一个整数数组 distance 。

从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说,每次移动后你的方位会发生逆时针变化。

判断你所经过的路径是否相交。如果相交,返回 true ;否则,返回 false 。

示例 1:

在这里插入图片描述
输入:distance = [2,1,1,2]
输出:true

示例 2:

在这里插入图片描述
输入:distance = [1,2,3,4]
输出:false

示例 3:

在这里插入图片描述
输入:distance = [1,1,1,1]
输出:true

提示:

1 <= distance.length <= 10^5
1 <= distance[i] <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/self-crossing
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

不会做,但是看了答案,感觉这题也没多大意思
就是列举出发生交叉的情况,然后判断就行了

class Solution {
    public boolean isSelfCrossing(int[] distance) {
        //想想怎么做,不会
        //看了题解,竟然是找出相交的三种情况,然后分别讨论...
        //这题感觉意义不大

        int l = distance.length;
        if(l < 4)
            return false;
        //考虑前六步
        for(int i = 3; i < l; i++){
            //第一种情况,第一条线和第四条线相交
            if(distance[i] >= distance[i - 2] && distance[i - 1] <= distance[i - 3])
                return true;
            //第二种情况,第一条线和第五条线重合
            if(i >= 4 && distance[i - 1] == distance[i - 3] &&  distance[i] + distance[i - 4] >= distance[i - 2])
                return true;
            //第三种情况,第一条线和第六条线相交
            if(i >= 5 && distance[i - 2] > distance[i - 4] && distance[i - 1] < distance[i - 3] && distance[i] + distance[i - 4] >= distance[i - 2] && distance[i - 1] + distance[i - 5] >= distance[i - 3])
                return true;
        }
        return false;
    }
}

260. 只出现一次的数字 III

2021.10.30 每日一题

题目描述

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?

示例 1:

输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。

示例 2:

输入:nums = [-1,0]
输出:[-1,0]

示例 3:

输入:nums = [0,1]
输出:[1,0]

提示:

2 <= nums.length <= 3 * 10^4
-2^31 <= nums[i] <= 2^31 - 1
除两个只出现一次的整数外,nums 中的其他数字都出现两次

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

也是做了很多遍的题了,主要是要用到异或的特点
两个相同的数异或为零,所以如果这个数组中有一个单独的数的话很好找出来
但是有两个单独的数该怎么办呢?
其他成对出现的数异或就是0,而两个单独的数因为不相同,所以异或肯定不是0,那么就至少有一个二进制位是不同的,找出这个二进制位,然后根据这个二进制位将这组数分成两组,然后再分别异或
具体而言,就是先将所有数异或,求出一个异或值,然后找到这个异或值的一个不为0的二进制位,然后根据这个二进制位分组

class Solution {
    public int[] singleNumber(int[] nums) {
        //根据每两个相同的数字异或以后是0的结论,这里有两个不同的数字,那么需要将它们进行分组
        //如何分组呢,先将所有数字异或,得到的数字就是两个不同数字的异或结果,因为异或是不同为1
        //那么找到这个结果中为1的位数,根据这个位数进行分组,就可以将两个不同的数字分到两个组
        int x = 0;
        for(int num : nums){
            x ^= num;
        }
        //取出x的最低位
        int div = 1;
        while((div & x) == 0){
            div <<= 1;
        }

        //这时候div就是分割点
        int a = 0;
        int b = 0;
        for(int num : nums){
            if((num & div) == 0) 
                a ^= num;
            else
                b ^= num;
        }
        return new int[]{a, b};
    }
}

500. 键盘行

2021.10.31 每日一题

题目描述

给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。

美式键盘 中:

  • 第一行由字符 “qwertyuiop” 组成。
  • 第二行由字符 “asdfghjkl” 组成。
  • 第三行由字符 “zxcvbnm” 组成。

American keyboard

示例 1:

输入:words = [“Hello”,“Alaska”,“Dad”,“Peace”]
输出:[“Alaska”,“Dad”]

示例 2:

输入:words = [“omk”]
输出:[]

示例 3:

输入:words = [“adsdf”,“sfd”]
输出:[“adsdf”,“sfd”]

提示:

1 <= words.length <= 20
1 <= words[i].length <= 100
words[i] 由英文字母(小写和大写字母)组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/keyboard-row
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

其实很简单么,就是记录每一行的字母,然后判断每个单词所有字母是否都在同一行
学一下官解这种将字符变成数字的方法,这样很方便,就是写这个字符串有点麻烦

class Solution {    
    public String[] findWords(String[] words) {
        List<String> list = new ArrayList<String>();
        String rowIdx = "12210111011122000010020202";
        for (String word : words) {
            boolean isValid = true;
            char idx = rowIdx.charAt(Character.toLowerCase(word.charAt(0)) - 'a');
            for (int i = 1; i < word.length(); ++i) {
                if (rowIdx.charAt(Character.toLowerCase(word.charAt(i)) - 'a') != idx) {
                    isValid = false;
                    break;
                }
            }
            if (isValid) {
                list.add(word);
            }
        }
        String[] ans = new String[list.size()];
        for (int i = 0; i < list.size(); ++i) {
            ans[i] = list.get(i);
        }
        return ans;
    }
}

三叶姐的,学两点:跳出外层循环 and 将list转换成数组(方法中要给定数组的形式)

class Solution {
    static String[] ss = new String[]{"qwertyuiop", "asdfghjkl", "zxcvbnm"};
    static int[] hash = new int[26];
    static {
        for (int i = 0; i < ss.length; i++) {
            for (char c : ss[i].toCharArray()) hash[c - 'a'] = i;
        }
    }
    public String[] findWords(String[] words) {
        List<String> list = new ArrayList<>();
        out:for (String w : words) {
            int t = -1;
            for (char c : w.toCharArray()) {
                c = Character.toLowerCase(c);
                if (t == -1) t = hash[c - 'a'];
                else if (t != hash[c - 'a']) continue out;
            }
            list.add(w);
        }
        return list.toArray(new String[list.size()]);
    }
}


作者:AC_OIer
链接:https://leetcode-cn.com/problems/keyboard-row/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-zx6b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值