每日一练(day05)

Posted 'or 1 or 不正经の泡泡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一练(day05)相关的知识,希望对你有一定的参考价值。

前言

最大的骄傲于最大的自卑都表示心灵的最软弱无力。——斯宾诺莎

题目

最后一个单词长度

先来一个开胃小菜

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。

单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

示例 1:

输入:s = “Hello World” 输出:5 示例 2:

输入:s = " fly me to the moon " 输出:4 示例 3:

输入:s = “luffy is still joyboy” 输出:6

这里注意的就是那个每个单词的空格 不是唯一的,所以要从后面扫描。

class Solution
    public int lengthOfLastWord(String s) 
        int length = 0;
        for(int i = s.length()-1;i>=0;i--)
            if(Character.isLetterOrDigit(s.charAt(i)))
                length ++;
            else if (length>0)
                break;
            
        
        return length;

    

搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

示例 1:

输入: nums = [1,3,5,6], target = 5 输出: 2 示例 2:

输入: nums = [1,3,5,6], target = 2 输出: 1

不用看二分查找

class Solution 
    public int searchInsert(int[] nums, int target) 
        int n = nums.length;
        int left = 0, right = n - 1, ans = n;
        while (left <= right) 
            int mid = ((right - left) / 2) + left;
            if (target <= nums[mid]) 
                ans = mid;
                right = mid - 1;
             else 
                left = mid + 1;
            
        
        return ans;
    

或者直接找也可以

class Solution 
    public int searchInsert(int[] nums, int target) 
        for(int i=0;i<nums.length;i++)
            if(target<=nums[i])
                return i;
            
        
        if(target<=nums[0])
            return 0;
        
        return nums.length;
    


删除重复的电子邮箱

这个是个mysql 的题目,就是叫你写sql语句

编写一个 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 p1 from Person p1,Person p2 where p1.Email = p2.Email and p1.Id > p2.Id

这里之所以可以实现这样的效果其实是因为,那个我们

select p1 from Person p1,Person p2 

的时候我们得到的结果其实是一个笛卡尔积,所以我们是可以通过上面的方式来进行删除的。

Nim 游戏

你和你的朋友,两个人一起玩 Nim 游戏: 桌子上有一堆石头。 你们轮流进行自己的回合,你作为先手。 每一回合,轮到的人拿掉 1 - 3
块石头。 拿掉最后一块石头的人就是获胜者。 假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n
的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false 。 示例 1: 输入: n = 4 输出:false
解释:如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。 示例 2: 输入:n = 1 输出:true

这个是个脑筋急转弯。
特点就是,由于最多只能那三个石头,所以如果有一个人拿的时候剩下4个石头,那么这个人必输无疑。

由于是我先拿,我一次最多拿三个,所以对于四个我必输,对于8个我其实也必输,因为无论我怎么拿,对面都可以保证留到四个给我(1+3=4)。所以只要是4倍数对我就不利。

class Solution 
    public boolean canWinNim(int n) 
        return n % 4 != 0;
    


单词规律

给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。

示例1:

输入: pattern = “abba” , str = “dog cat cat dog”
示例 2:

输入:pattern = “abba” , str = “dog cat cat fish”

输出: false 示例 3:

输入: pattern = “aaaa” , str = “dog cat cat dog”

输出: false 示例 4:

输入: pattern = “abba” , str = “dog dog dog dog”

输出: false

这个没啥好说的,搞两个 字典存起来(python的看起来明朗一点)

class Solution:
    def wordPattern(self, pattern, s):
        wordtoch = 
        chtoword = 
        words = s.split()
        if len(pattern) != len(words):
            return False
        
        for ch, word in zip(pattern, words):
            if (word in wordtoch and wordtoch[word] != ch) or (ch in chtoword and chtoword[ch] != word):
                return False
            wordtoch[word] = ch
            chtoword[ch] = word
    
        return True

然后是java的

class Solution 
    public boolean wordPattern(String pattern, String str) 

        Map<String, Character> patternaskey = new HashMap<String, Character>();
        Map<Character, String> straskey = new HashMap<Character, String>();

        int m = str.length();
        int i = 0;
        for (int p = 0; p < pattern.length(); ++p) 
            char ch = pattern.charAt(p);

            if (i >= m)
                
                    return false;
                
            int j = i;
            while (j < m && str.charAt(j) != ' ')
                
                    j++;
                
            String tmp = str.substring(i, j);
            //  假设abac  dog cat dog cat  --> 在 straskey.get("cat") -->b 但是此时为 c 不符合
            if (patternaskey.containsKey(tmp) && patternaskey.get(tmp) != ch)
                
                    return false;
                
            if (straskey.containsKey(ch) && !tmp.equals(straskey.get(ch)))
                
                    return false;
                

            patternaskey.put(tmp, ch);
            straskey.put(ch, tmp);
            i = j + 1;
        
        return i >= m;
    


反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = [“h”,“e”,“l”,“l”,“o”] 输出:[“o”,“l”,“l”,“e”,“h”] 示例 2:

输入:s = [“H”,“a”,“n”,“n”,“a”,“h”] 输出:[“h”,“a”,“n”,“n”,“a”,“H”]

这里懂的都懂,但是这里的话给一个不需要额外空间的方法

class Solution 
    public void reverseString(char[] s) 
        for(int i=0,j=s.length-1;i<j;i++,j--)
            s[j] = (char) (s[i]+s[j]);
            s[i] = (char) (s[j]-s[i]);
            s[j] = (char) (s[j]-s[i]);

        
    

反转元音字母

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。

元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现。

示例 1:

输入:s = “hello” 输出:“holle” 示例 2:

输入:s = “leetcode” 输出:“leotcede”

这个没啥,就是注意判断元音字母

class Solution 
    public String reverseVowels(String s) 
        int n = s.length();
        char[] arr = s.toCharArray();
        int i = 0, j = n - 1;
        while (i < j) 
            while (i < n && !isVowel(arr[i])) 
                ++i;
            
            while (j > 0 && !isVowel(arr[j])) 
                --j;
            
            if (i < j) 
                swap(arr, i, j);
                ++i;
                --j;
            
        
        return new String(arr);
    

    public boolean isVowel(char ch) 
        return "aeiouAEIOU".indexOf(ch) >= 0;
    

    public void swap(char[] arr, int i, int j) 
        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        //运算要点时间,反而更慢了
//        arr[j] = (char) (arr[i]+arr[j]);
//        arr[i] = (char) (arr[j]-arr[i]);
//        arr[j] = (char) (arr[j]-arr[i]);
    


总结

今天就这样吧,明天开始多刷一刷和树,图有关的简单单题,然后我们就去干中档题。现在还是简单和中档穿插,后面以中档为主。

以上是关于每日一练(day05)的主要内容,如果未能解决你的问题,请参考以下文章

每日一练(day02 手撕 KMP)

每日一练(day09补08,03,04)

每日一练(day12&PriorityQueue)

每日一练(day04)

每日一练(day03--动态规划dp)

每日一练(day10)