力扣练习4(十题)

Posted 冷血~多好

tags:

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

1.(412) Fizz Buzz

给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:

answer[i] == "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。
answer[i] == "Fizz" 如果 i 是 3 的倍数。
answer[i] == "Buzz" 如果 i 是 5 的倍数。
answer[i] == i 如果上述条件全不满足。

例 1:

输入:n = 3
输出:["1","2","Fizz"]
示例 2:

输入:n = 5
输出:["1","2","Fizz","4","Buzz"]
示例 3:

输入:n = 15
输出:["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]
 

提示:

1 <= n <= 104

class Solution 
    public List<String> fizzBuzz(int n) 


   List<String> list=new ArrayList<>();
        for(int i=1;i<=n;i++)
            if(i%3==0&&i%5==0)
                list.add("FizzBuzz");
            
            else if(i%3==0)
                list.add("Fizz");
            
            else if(i%5==0)
                list.add("Buzz");
            
            else 
             list.add(String.valueOf(i));
            
        


        return list;

    

2. 剑指 Offer II 069. 山峰数组的顶部

符合下列属性的数组 arr 称为 山峰数组(山脉数组) :

arr.length >= 3
存在 i(0 < i < arr.length - 1)使得:
arr[0] < arr[1] < ... arr[i-1] < arr[i]
arr[i] > arr[i+1] > ... > arr[arr.length - 1]
给定由整数组成的山峰数组 arr ,返回任何满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i ,即山峰顶部。

示例 1:

输入:arr = [0,1,0]
输出:1
示例 2:

输入:arr = [1,3,5,4,2]
输出:2
示例 3:

输入:arr = [0,10,5,2]
输出:1
示例 4:

输入:arr = [3,4,5,1]
输出:2
示例 5:

输入:arr = [24,69,100,99,79,78,67,36,26,19]
输出:2
 

提示:

3 <= arr.length <= 104
0 <= arr[i] <= 106
题目数据保证 arr 是一个山脉数组

class Solution 
    public int peakIndexInMountainArray(int[] arr) 
        int n=0;
     int n2=0;
        for(int i=1;i<arr.length;i++)
            if(n<=arr[i])
                n2=i;   
                n=arr[i];                      
                 
                 else
                     break;
                 
        
        return n2;

    

3.(17) 电话号码的字母组合

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:

输入:digits = ""
输出:[]
示例 3:

输入:digits = "2"
输出:["a","b","c"]
 

提示:

0 <= digits.length <= 4
digits[i] 是范围 ['2', '9'] 的一个数字。

class Solution 

    public List<String> letterCombinations(String digits) 


            List<List<String>> lists=new ArrayList<>();
            List<String> list=new ArrayList<>();
            list.add("a");list.add("b");list.add("c");lists.add(list);list= new ArrayList<>();
            list.add("a");list.add("b");list.add("c");lists.add(list);list= new ArrayList<>();
            list.add("a");list.add("b");list.add("c");lists.add(list);list= new ArrayList<>();
            list.add("d");list.add("e");list.add("f");lists.add(list);list= new ArrayList<>();
            list.add("g");list.add("h");list.add("i");lists.add(list);list= new ArrayList<>();
            list.add("j");list.add("k");list.add("l");lists.add(list);list= new ArrayList<>();
            list.add("m");list.add("n");list.add("o");lists.add(list);list= new ArrayList<>();
            list.add("p");list.add("q");list.add("r");list.add("s");lists.add(list);list= new ArrayList<>();
            list.add("t");list.add("u");list.add("v");lists.add(list);list= new ArrayList<>();
            list.add("w");list.add("x");list.add("y");list.add("z");lists.add(list);
//        for(int i=0;i<lists.size();i++)
//            list= lists.get(i);
//            for(int j=0;j<list.size();j++)
//                System.out.println(list.get(j));
//            
//        
        List<String> list0=new ArrayList<>();

      if(digits.length()>0&&digits.length()<=1)

          list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
          for(int i=0;i<list.size();i++)
              list0.add(list.get(i));
          


      
      else if(digits.length()>1&&digits.length()<=2)
         
          list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
          for(int i=0;i<list.size();i++)
          String  s=list.get(i);
            List<String>  list2=lists.get(Integer.parseInt(String.valueOf(digits.charAt(1))));
            for(int j=0;j<list2.size();j++)
               list0.add(s+list2.get(j));
//["ad","ae","af","bd","be","bf","cd","ce","cf"]
            
          
          


      
      else if(digits.length()>2&&digits.length()<=3)

          list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
          for(int i=0;i<list.size();i++)
              String  s=list.get(i);
              List<String>  list2=lists.get(Integer.parseInt(String.valueOf(digits.charAt(1))));
              for(int j=0;j<list2.size();j++)
                 String s2=list2.get(j);
                  List<String>  list3=lists.get(Integer.parseInt(String.valueOf(digits.charAt(2))));
                  for(int k=0;k<list3.size();k++)
                      list0.add(s+s2+list3.get(k));
                  
              
          


      
      else if(digits.length()>3&&digits.length()<=4)

          list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
          for(int i=0;i<list.size();i++)
              String  s=list.get(i);
              List<String>  list2=lists.get(Integer.parseInt(String.valueOf(digits.charAt(1))));
              for(int j=0;j<list2.size();j++)
                  String s2=list2.get(j);
                  List<String>  list3=lists.get(Integer.parseInt(String.valueOf(digits.charAt(2))));
                  for(int k=0;k<list3.size();k++)
                      String s3=list3.get(k);
                      List<String>  list4=lists.get(Integer.parseInt(String.valueOf(digits.charAt(3))));
                      for(int p=0;p<list4.size();p++)
                          list0.add(s+s2+s3+list4.get(p));
                      
                  
              
          

      

        return list0;


    

4.(24) 两两交换链表中的节点

/**
 * Definition for singly-linked list.
 * public class ListNode 
 *     int val;
 *     ListNode next;
 *     ListNode() 
 *     ListNode(int val)  this.val = val; 
 *     ListNode(int val, ListNode next)  this.val = val; this.next = next; 
 * 
 */
class Solution 
    public ListNode swapPairs(ListNode head) 

   
   if(head==null||head.next==null)

            return head;
        

        ListNode list1=new ListNode();
        ListNode list2=new ListNode();
        ListNode list3=new ListNode();
        ListNode list4=new ListNode();
        ListNode head2=list4;
        while(true)

            if(head==null||head.next==null)
                break;
            
            list1=head;
            list2=list1.next;
            list3=list2.next;

            list4.next=list2;
            list2.next=list1;
            list1.next=list3;

            head=list3;
            list4=list4.next.next;
         //   System.out.println(list4.val);

        
        return head2.next;
    

5.(29) 两数相除

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:

输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
 

提示:

被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231,  231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

class Solution 
    int num=0;
  public  int divide(int dividend, int divisor) 
        // 考虑被除数为最小值的情况
        if (dividend == Integer.MIN_VALUE) 
            if (divisor == 1) 
                return Integer.MIN_VALUE;
            
            if (divisor == -1) 
                return Integer.MAX_VALUE;
            
        
        // 考虑除数为最小值的情况
        if (divisor == Integer.MIN_VALUE) 
            return dividend == Integer.MIN_VALUE ? 1 : 0;
        
        // 考虑被除数为 0 的情况
        if (dividend == 0) 
            return 0;
        
        boolean b=false;
        boolean b2=false;
        boolean b3=false;
        if(dividend>0)
            dividend=-dividend;
            b=true;
        
        if(divisor>0)
            divisor=-divisor;
            b2=true;
        
          if(dividend>divisor)
            return 0;
        
        if(dividend==Integer.MIN_VALUE)
            dividend=dividend+1;
            b3=true;
        
        int m=add(dividend,divisor,0);

         if(b3)
            if((num-1)==divisor) 
                m = m + 1;
            
        
      if(b&&b2)
       return m;
     
      else if(b==false&&b2==false)
          return m;
      


        return -m;
    

    public  int add(int dividend, int divisor,int n)
    
        int i=0;
        int  divisor2=0;
        while (true)
         divisor2=divisor<<i;

         if(divisor2<dividend||divisor2>0)
             divisor2=divisor<<(i-1);
             while (divisor2>0)
                 i--;
                 divisor2=divisor<<(i-1);
             

             break;
         
         i++;
        


        dividend=dividend-divisor2;
        if(dividend>divisor)
            num=dividend;
            return (1<<i-1)+n;
        


        return     add(dividend,divisor,(1<<i-1))+n;



    

6.(34) 在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]。

进阶:

你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:

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

提示:

0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109。

class Solution 
    public int[] searchRange(int[] nums, int target) 

boolean b1=false;
boolean b2=false;
      int n[]=new int[2];
      for(int i=0;i<nums.length;i++)
          if(nums[i]==target)
              n[0]=i;
              b1=true;
              break;
          
      

      for(int i=nums.length-1;i>=0;i--)
          if(nums[i]==target)
              n[1]=i;
              b2=true;
              break;
          
      
      if(b1&&b2)
           return n;
      
   n[0]=-1;
   n[1]=-1;
      return n;
    

7.(38) 外观数列

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221
第一项是数字 1 
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 "3322251" 的描述如下图:

class Solution 
   static String num[]=new String[30];
    static int sum2=1;
     static 
          num[0]="1";
        sum("1");
    
    public String countAndSay(int n) 

     
      return num[n-1];
    

      public static  void sum(String s)
        
            char s1 = 0;
           StringBuilder stringBuilder=new StringBuilder();
        int k=0;
        for(int i=0;i<s.length();i++)

            if(i==0)
                s1=s.charAt(i);
                if(s.length()==1)
                    stringBuilder.append(String.valueOf(i+1)+s1);
                
            
            else 
                if(s1!=s.charAt(i))
                   // s3=String.valueOf(i+1-k)+s1;
                    stringBuilder.append(String.valueOf(i-k)+s1);
                    s1=s.charAt(i);
                    k=i;
                
                 if(i==s.length()-1&&s1==s.charAt(i))
                    stringBuilder.append(String.valueOf(i+1-k)+s1);
                
                else if(i==s.length()-1&&s1!=s.charAt(i))
                    stringBuilder.append(String.valueOf(i-k)+s.charAt(i));
                
            

        
            num[sum2]=String.valueOf(stringBuilder);
           if(sum2==29)
              return;
          
           sum2++;
                sum( num[sum2-1]);

    

8.(211) 添加与搜索单词 - 数据结构设计

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary :

WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回  false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。

示例:

输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]

解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True
 

提示:

1 <= word.length <= 500
addWord 中的 word 由小写英文字母组成
search 中的 word 由 '.' 或小写英文字母组成
最多调用 50000 次 addWord 和 search

class WordDictionary 
 HashMap<Integer, Set<String>> map;
     public WordDictionary() 
            map = new HashMap<>();
        

        public void addWord(String word) 
           int n=word.length();
           if(map.get(n)!=null)
             map.get(n).add(word);
           
           else 
               Set<String> s=new HashSet<>();
               s.add(word);
               map.put(n,s);
           

        

    public boolean search(String word) 


            int k=0;
        Set<String> s=map.get(word.length());
         if(s== null)
            return false;
        
        for(String s2:s)

            for(int j=0;j<word.length();j++)

                if(word.charAt(j)!='.'&&s2.charAt(j)!=word.charAt(j))
                    k++;
                    break;
                
            
            if(k==0)
                return true;
            
            k=0;
        



        return false;

    



/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.addWord(word);
 * boolean param_2 = obj.search(word);
 */

9.( 71) 简化路径

给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

始终以斜杠 '/' 开头。
两个目录名之间必须只有一个斜杠 '/' 。
最后一个目录名(如果存在)不能 以 '/' 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。
返回简化后得到的 规范路径

例 1:

输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。 
示例 2:

输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:

输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:

输入:path = "/a/./b/../../c/"
输出:"/c"
 

提示:

1 <= path.length <= 3000
path 由英文字母,数字,'.','/' 或 '_' 组成。
path 是一个有效的 Unix 风格绝对路径。

class Solution 
    public String simplifyPath(String path) 

  String s[]=path.split("/");
        Stack<String> stack=new Stack<>();
        for(String str:s)
            if(str.equals("")||str.equals("."))
                continue;
            
            if(str.equals(".."))
                if(!stack.empty())
                stack.pop();
            else 
                stack.push(str);
            
        
      

   return "/"+String.join("/",stack);
        

    

 10.(217) 存在重复元素

给定一个整数数组,判断是否存在重复元素。

如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。

示例 1:

输入: [1,2,3,1]
输出: true
示例 2:

输入: [1,2,3,4]
输出: false
示例 3:

输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

class Solution 
    public boolean containsDuplicate(int[] nums) 
       Arrays.sort(nums);
        for(int i=0;i<nums.length;i++)

        if((i+1<nums.length)&&nums[i]==nums[i+1])
        return true;
        

        
        return false;

    


以上是关于力扣练习4(十题)的主要内容,如果未能解决你的问题,请参考以下文章

力扣练习4(十题)

力扣练习4(十题)

力扣练习4(十题)

力扣练习4(十题)

JAVA自除数——力扣每日一题(2022.03.31)

力扣 练习2(十题)