力扣的剑指offer算法

这篇博客涵盖了多种编程题目,包括字符串空格替换、整数转换、正则表达式匹配、链表操作等。讨论了如何高效地实现这些功能,如使用动态规划、递归、栈等数据结构和算法,同时涉及了二叉搜索树、斐波那契数列、位运算等概念。文章展示了如何通过Java实现这些解决方案,并分析了不同方法的时间和空间复杂度。
摘要由CSDN通过智能技术生成

字符串

**剑指 Offer 05. 替换空格 第一道题3.19**

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZHNHsZ6-1626916827939)(C:\Users\12479\AppData\Roaming\Typora\typora-user-images\image-20210319215145157.png)]

并且’-'负号为45

示例 1:

输入:s = "We are happy."
输出:"We%20are%20happy."
//方法一:利用了Array数组
class Solution{
    public String replaceString(String s ){
        char[] array = new char[s.length() * 3 ];
        int size = 0;
        for(int i= 0;i <s.length();i++){
            char c = s.charAt(i );
            if (' '==c ){
                array[size++] = '%';
                array[size++] = '2';
                array[size++] = '0';
            }else{
                array[size++] = c;
            }
        }
        //一个数组转换成字符串;
        String nes = new String(array,0 ,size);
        return nes;
    }
        }
//方法二.这个方法速度快一点,利用StringBulider
class Slotion2{
    public String repaceSpace(String s){
        StringBuilder sb= new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (' ' == s.charAt(i)){
                sb.append("%20");
            }else {
                sb.append(s.charAt(i ));
            }
        }
        return sb.toString();
    }
}

剑指 Offer 67. 把字符串转换成整数

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

输入: "42"
输出: 42

示例 2:

输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

示例 5:

输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
     因此返回 INT_MIN (−231) 。

代码


剑指 Offer 19. 正则表达式匹配

请实现一个函数用来匹配包含'. ''*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a""ab*ac*a"匹配,但与"aa.a""ab*a"均不匹配。

方法一:

利用java 的函数

class Solution{
    public boolean isMatch(String s, String p) {
        return s.matches(p);
    }
}


方法二:动态规划

class Solution {
    public boolean isMatch(String s, String p) {
        int m = s.length();
        int n = p.length();

        boolean[][] f = new boolean[m + 1][n + 1];
        f[0][0] = true;
        for (int i = 0; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (p.charAt(j - 1) == '*') {
                    f[i][j] = f[i][j - 2];
                    if (matches(s, p, i, j - 1)) {
                        f[i][j] = f[i][j] || f[i - 1][j];
                    }
                } else {
                    if (matches(s, p, i, j)) {
                        f[i][j] = f[i - 1][j - 1];
                    }
                }
            }
        }
        return f[m][n];
    }

    public boolean matches(String s, String p, int i, int j) {
        if (i == 0) {
            return false;
        }
        if (p.charAt(j - 1) == '.') {
            return true;
        }
        return s.charAt(i - 1) == p.charAt(j - 1);
    }
}

链表

剑指 Offer 18. 删除链表的节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

**注意:**此题对比原题有改动

方法 1:

没有用到带头结点的

 class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode pDeleteFront = head;
            if(head.val ==val){
                head = head.next;
            }else{
                while(pDeleteFront.next.val !=val&&pDeleteFront.next!=null){
                    pDeleteFront = pDeleteFront.next;
                }
                if(pDeleteFront.next.val==val){
                     ListNode  deleltedNode;
                     deleltedNode = pDeleteFront.next;
                    pDeleteFront.next = deleltedNode.next;

                }
            }
        
            return head;
        }

        
        
    }
    
方法2:

下面这个方法,仍然需要遍历整个链表,找到这值的节点,

时间复杂度为o(n)平均,空间为O(1);

这里给的是val一个节点的值,而不是一个节点的;如果给节点,可以用节点后面的一个节点复制给当前节点,然后删除当前节点,就能实现O(1)的复杂度了;

class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        if(head.val ==val){
            return head.next;
        }
        ListNode  creedentnode =head.next;
        ListNode prenode =head;
        while(creedentnode.next!=null &&creedentnode.val!=val){
            prenode = creedentnode;
            creedentnode = creedentnode.next;
        }
        prenode.next =creedentnode.next;
        return head;

    }
}
剑指 Offer 22. 链表中倒数第k个节点

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.
class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        if(head ==null || k <1){
            return null;
        
}
    ListNode fast=head;
       //相当于for(i=1;i<k;i++).块指针fast走了k-1步.
    while(k-->1){
        if(fast.next ==null){
            return null;
        }else{
            fast = fast.next;
        }
    }
    ListNode slow = head;
        //块指针走到尾节点停下.不是走到了null节点才停下的
    while(fast.next !=null){
        fast = fast.next;
        slow = slow.next;
    }
    
    return slow;
    
}

}

剑指 Offer 06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

用栈,

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public int[] reversePrint(ListNode head) {
      
           
         Deque<Integer> stack = new LinkedList<Integer>();
           ListNode dummy = head;
           int count =0;
           while(dummy != null){
               stack.push(dummy.val);
            
               count++;
               dummy = dummy.next;
           }
        int[] arr = new int[count];
        
           while(!stack.isEmpty()){
               for (int i = 0; i < count ; i++) {
                   
                   arr[i] =stack.pop();
               }
           }

            return arr;
    }
}

用递归

class Solution {
    ArrayList<Integer> tmp = new ArrayList<Integer>();
    public int[] reversePrint(ListNode head) {
        recur(head);
        int[] res = new int[tmp.size()];
        for(int i = 0; i < res.length; i++)
            res[i] = tmp.get(i);
        return res;
    }
    void recur(ListNode head) {
        if(head == null) return;
        recur(head.next);
        tmp.add(head.val);
    }
}

作者:jyd
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/mian-shi-ti-06-cong-wei-dao-tou-da-yin-lian-biao-d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
剑指 Offer 24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

递归

class Solution {
    public ListNode reverseList(ListNode head) {
        //@1:head刚开始不是0.到达尾结点停止.返回最后一个节点(不是返回null)
        if(head ==null ||head.next ==null){
            return head;
        }
        //此时的head.next是null.head是尾结点.之后才会执行@1
        ListNode  node =  reserveList( head.next);
        //下面的内容第一次执行时.从倒数第二个开始.倒数第二个节点的下一个节点(尾结点)的next= 倒数第二个节点.
        //之后.这些归内容依次执行.. 
        
        head.next.next =head;
        head.next =null;
        return node;
    }
}

迭代

防止断链,至少放置三个指针,中间的node,后面的next,最前面的pre;如果要返回,

还需要一个最后面指向尾结点的指针reservenode;如果不用最后这个,可以返回pre;

    public ListNode reverseList(ListNode head) {
        //最前面的pre
        ListNode prev = null;
        //中间的node,
        ListNode curr = head;
        while(curr !=null){
            //后面的next
            ListNode next  = curr.next;
           // If
            curr.next = prev;
            prev = curr;
            curr = next;
            
        }
        return prev;
    }
}

例如这样:

还需要一个最后面指向尾结点的指针reservenode;如果不用最后这个,可以返回pre;

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev= null;
        ListNode reverse= new ListNode(0);
        ListNode curr = head;
        while(curr !=null){
            ListNode next = curr.next; 
            if(next ==null){
                reverse = curr;
            }
            curr.next = prev;
            prev = curr;
            curr = next;
           
       
    }
         return reverse;
}
}

class Solution {
    Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>();
    Set<Integer> visited = new HashSet<Integer>();

    public void dfs(TreeNode root) {
        if (root.left != null) {
            parent.put(root.left.val, root);
            dfs(root.left);
        }
        if (root.right != null) {
            parent.put(root.right.val, root);
            dfs(root.right);
        }
    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        dfs(root);
        while (p != null) {
            visited.add(p.val);
            p = parent.get(p.val);
        }
        while (q != null) {
            if (visited.contains(q.val)) {
                return q;
            }
            q = parent.get(q.val);
        }
        return null;
    }
}


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/er-cha-shu-de-zui-jin-gong-gong-zu-xian-6fdt7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
剑指 Offer 25. 合并两个排序的链表

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->

迭代的算法:

方便理解,但是代码不简洁;

时间都是O(n)=M+N

空间是O(1)


class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode margeList = new ListNode(-1);
    
        if(l1==null){
            return l2;
        }else if(l2==null){
            return l1;
        }
        if(l1.val<l2.val){
            margeList= l1;
            margeList.next= mergeTwoLists(l1.next,l2);
        }else{
            margeList =l2;
            margeList.next= mergeTwoLists(l1,l2.next);
        }
        return margeList;
    }
}
            while (l1 != null && l2 != null) {
                if (l1.val < l2.val) {
                    
                   node.next= l1;
                   
                    l1 =l1.next;
                }else {
                   
                   node.next =l2;
                   
                    l2 =l2.next;
                }
                
                 node =node.next;
            }
            if (l1 != null) {
                  node.next = l1;
             }
             if ((l2 != null)) {
                    node.next = l2;
            }
            




            return curr.next;
        
    }
}

方法二:递归

时间:M+N

空间:M+N

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode margeList = new ListNode(-1);
    
        if(l1==null){
            return l2;
        }else if(l2==null){
            return l1;
        }
        if(l1.val<l2.val){
            margeList= l1;
            margeList.next= mergeTwoLists(l1.next,l2);
            //注意,这里不能用if()替换到else{};这里要保证每次递归必须有一个放到形成的新的链表的元素
        }else{
            margeList =l2;
            margeList.next= mergeTwoLists(l1,l2.next);
        }
        return margeList;
    }
}

剑指 Offer 54. 二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第k大的节点。

说明:中序遍历的逆遍历

示例 1:

输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 4
class Solution {
    int vals =0;
    int k=0;
    
    public int kthLargest(TreeNode root, int k) {
        if(root ==null||k<0){
            return -1;
        }
        this.k = k;
        
        //Deque<Integer> stack = new LinkedList<>();
        dfs (root);
        return vals;
    }
    void dfs(TreeNode root){
        if(root == null)
        return;
         if(k==0){
            return ;
        }
            dfs(root.right);
            k--;
            if(k==0){
                vals = root.val;
            }
            dfs(root.left);
            }
        }

递归

剑指 Offer 10- II. 青蛙跳台阶问题

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:2

示例 2:

输入:n = 7
输出:21
class Solution {
    public int numWays(int n) {
       
           if( n ==1||n == 0){
            return 1;  
        }
       
         
        int a=1;
        int b=1;
        int c=0;
        for(int i=2;i<=n;i++){
            c=(a+b)%1_000_000_007;
            a=b;
            b=c;
        }
        return c;


    }
}
剑指 Offer 10- I. 斐波那契数列

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

class Solution {
    public int fib(int n) {
        int []num= new int[]{0,1};
        if(n<2){
            return num[n];
        }
        
        
       int fOne =0;
        int fTwo=1;
        int fn =0;
        for(int i=2;i<=n;++i){
            fn =(fOne+fTwo)%1000000007;
            fOne=fTwo;
            fTwo=fn;
        }
        
        return fn;
        

这两道题的初值不同而已;

数组

剑指 Offer 03. 数组中重复的数字

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3 

说明:

​ 在遍历中,交换每个数组的数字,让它和自己的下标对应的数字对齐;@1

当遍历到这个数字.他对应的下标不同,并且是与他应该对应的那个值是相同的,但是是已经对齐的.就赋值个a返回;@2

class Solution {
    public int findRepeatNumber(int[] nums) {
       if(nums.length<1){
           return -1;
       }
       int a =0;
       for(int i=0;i<nums.length;i++){
           //(@1)
           int temp =nums[i];
           nums[i]=nums[temp];
           nums[temp]= temp;
			//@2
           while(nums[i]!=i){
               if(nums[i] ==nums[nums[i]]){
                   a=nums[i];
                   break;
               }

              
           }
       }
       return a;

    }
}
剑指 Offer 39. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

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

//1可以用一个hashmap遍历,记录,可以在idea跑,不知为啥不能在力扣跑全部的例子

​ hashmap的方法,时间和空间都是O(N)

2可以用摩尔投票法

​ 时间是O(N);空间可以是O(1);

class Solution {
        public int majorityElement(int[] nums) {
            Map<Integer,Integer> map= new HashMap<>();
            int c=0;
            int b=1;
            for(int i=0;i<nums.length;i++){

                if(map.containsKey(nums[i])){
                    b++;
                    map.put(nums[i],b);
                }else{
                    map.put(nums[i],b);
                }

            }

            for (int a : map.keySet()
            ){
             int value = map.get(a);
            if(value>nums.length/2){

                c=a;
                
            }

        }
            System.out.println(c);
           return c;


    }
}
class Solution {
    public int majorityElement(int[] nums) {
int x=0, votes=0;
        for (int num : nums
                ) {
                if (votes==0) x=num;
                if(num==x){
                votes=votes+1;

                }else {
                votes =votes-1;
                }
                }
                return x;
    }
}
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

解题思路:

  • 利用快排思想的划分思想;用low和high左右交换,达到O(n)的时间复杂度;常数级别的空间复杂度;
  • 最直接是想法就是发现是偶数, 拿出这个数字,其余的数组往前移动;空出末尾一个空间,把这个偶数放到末尾;
class Solution {
    public int[] exchange(int[] nums) {
        while(nums==null||nums.length < 0){
            return new int[0];
        }
        int low=0;
        int high=nums.length-1;
        while(low<high){
            while( low <high &&nums[low]%2!=0){
                low++;
            }
            while(low <high && nums[high]%2==0){
                high--;
            }
            if(low<high){
                int temp= nums[low];
                nums[low] = nums[high];
                nums[high] = temp;
            }
           
        }
        return  nums;

    }
}

位运算:

剑指 Offer 15. 二进制中1的个数

请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

(1)这种用于无符号的,在力扣运行,超时了;

//
public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count=0;
        while(n!=0){
            if((n&1)!=0){
                count++;
            }
            n=n>>1;

        }
        return count;
        
    }
}

(2)改变思路,不右移了;左移,并且可以做到不改变原来这个数的情况下进行,进行次数为32,int有关位数决定

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count=0;
        int flag=1;
        while(flag!=0){
            if((n&1)!=0){
                count++;
            }
            flag=flag<<1;
            n=n>>1;

        }
        return count;
        
    }
}

(3)思路:

一个整数例如1100(12)减一为1011(11);显然,原来的数字的倒数第一个为1的数字变为0,之后的0全部变为1;

利用这个性质;可以:让这个数与减一之后的数字做与运算;能做多少次,就说明有多少个1;

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
         int count=0;
         while(n!=0){
             n = n&(n-1);
             ++count;
         }
         return count;
        
    }
}
总结:

判断一个整数是2的整数次方,

  • ​ 如果是,例如(10)2,(100)4.这种,让他减一,在与其本身做与运算,若结果为0 ,则就是2的整数次方数;

输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n,

  • 可以让两数做异或(^):
  • 只有同为0或者同为1的数字异或是0;
  • 利用这个,异或 之后,判断1的个数就行;

其他

1数值,位运算;
剑指 Offer 16. 数值的整数次方

实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。

若选择用一次次的循环,会超时

class Solution {
    public double myPow(double x, int n) {
        if(x==0){
            return 0;
        } 
        double res=1.0;

        if(n<0){
            x=1/x;

        for(int i=0;i<Math.abs(n);i++){
            res*=x;
        }
        return res; 
        }else{

        }
        for(int i=0;i<n;i++){
            res*=x;
        }
        return res;

    }
}
(2)快速幂:

拆解指数幂n,让n表示成位的形式,观察样式发现:当为0的时候此位的时结果乘1,若为1不为0的时候,此位的结果是该位置结果的1*x(该有的m);

注意事项:当m指数为负时,转换为整数,在int中,负的int比正的int 多1,需要转换成long型的;

复杂度:空间为1

时间应该是o(logn)

class Solution {
    public double myPow(double x, int n) {
        long b=n;
        double res =1.0;
        if(x==0) return 0;
        if(b<0){
            x=1/x;
            b=-b;
        }
        //这里!=0和大于0都行,在多线程情况下,应该为大于0;
        while(b>0){
            if((b&1)==1)  res*=x;
            x*=x;
            b=b>>1;
        }
        return res;
    }
}

剑指 Offer 17. 打印从1到最大的n位数

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

示例 1:

输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]

(1)直接遍历的方法:

时间为o(10的N次方),用在了建立数列;

引用:

时间复杂度 O(10n)O(10^n)O(10n) : 生成长度为 10n10^n10n 的列表需使用 O(10n)O(10^n)O(10n) 时间。
空间复杂度 O(1)O(1)O(1) : 建立列表需使用 O(1)O(1)O(1) 大小的额外空间( 列表作为返回结果,不计入额外空间 )。

作者:jyd
链接:https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/solution/mian-shi-ti-17-da-yin-cong-1-dao-zui-da-de-n-wei-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution {
    public int[] printNumbers(int n) {
        int len= 1;
        for(int i=0;i<n;i++){
            len*=10;
        }
        int[]array=new int[len-1];
        for(int i=0;i<len-1;i++){
            array[i]=i+1;
        }
        return array;

    }
}

快速幂

应该差不

class Solution {
    public int[] printNumbers(int n) {
        if (n<=0){
            return new int[0];
        }
        int res=1;
        int x=10;

        while(n>0){
            if((n&1)==1) res*=x;
            x*=x;
            n=n>>1;
        }
        int len = res-1;
        int[]A =new int[len];
        for(int i=0;i<len;i++){
            A[i]=i+1;
        }
        return A;
    }

,2,3,4,5,6,7,8,9]


(1)直接遍历的方法:

时间为o(10的N次方),用在了建立数列;

引用:

时间复杂度 O(10n)O(10^n)O(10n) : 生成长度为 10n10^n10n 的列表需使用 O(10n)O(10^n)O(10n) 时间。
空间复杂度 O(1)O(1)O(1) : 建立列表需使用 O(1)O(1)O(1) 大小的额外空间( 列表作为返回结果,不计入额外空间 )。

作者:jyd
链接:https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/solution/mian-shi-ti-17-da-yin-cong-1-dao-zui-da-de-n-wei-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

```java
class Solution {
    public int[] printNumbers(int n) {
        int len= 1;
        for(int i=0;i<n;i++){
            len*=10;
        }
        int[]array=new int[len-1];
        for(int i=0;i<len-1;i++){
            array[i]=i+1;
        }
        return array;

    }
}

快速幂

应该差不

class Solution {
    public int[] printNumbers(int n) {
        if (n<=0){
            return new int[0];
        }
        int res=1;
        int x=10;

        while(n>0){
            if((n&1)==1) res*=x;
            x*=x;
            n=n>>1;
        }
        int len = res-1;
        int[]A =new int[len];
        for(int i=0;i<len;i++){
            A[i]=i+1;
        }
        return A;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值