leetcode剑指Offer1

剑指 Offer 16. 数值的整数次方

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

示例 1:

输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:

输入:x = 2.10000, n = 3
输出:9.26100
示例 3:

输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
求 x^nx
n
最简单的方法是通过循环将 nn 个 xx 乘起来,依次求 x^1, x^2, …, x^{n-1}, x^nx
,时间复杂度为 O(n)O(n) 。
快速幂法 可将时间复杂度降低至 O(log_2 n)O(log
2

2的5次方=2*4的平方

class Solution {
    public double myPow(double x, int n) {
        if(x==0)   return 0;
        double res=1;
        long b=n;
        if(b<0){
            x=1/x;
            b=-b;
        }
        while(b>0){
            if((b&1)==1)res*=x;
            x*=x;
            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]

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

应考虑大数运算,使用全排列来解。

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

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

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

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

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:

输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

    //双指针来实现遍历链表
    public ListNode deleteNode(ListNode head, int val) {
        if(head.val==val)return head.next;
        ListNode pre=head,cur=head.next;
        while(cur.val!=val&&cur!=null){
            pre=cur;cur=cur.next;
        }
        if(cur!=null) pre.next=cur.next;
        return head;
    }

剑指 Offer 20. 表示数值的字符串

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

数值(按顺序)可以分成以下几个部分:

若干空格
一个 小数 或者 整数
(可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:

(可选)一个符号字符(’+’ 或 ‘-’)
下述格式之一:
至少一位数字,后面跟着一个点 ‘.’
至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
一个点 ‘.’ ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:

(可选)一个符号字符(’+’ 或 ‘-’)
至少一位数字
部分数值列举如下:

["+100", “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非数值列举如下:

[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]

示例 1:

输入:s = “0”
输出:true
示例 2:

输入:s = “e”
输出:false
示例 3:

输入:s = “.”
输出:false
示例 4:

输入:s = " .1 "
输出:true
有限状态自动机

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

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

示例:

输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。

class Solution {
     public int[] exchange(int[] nums) {
         if(nums.length==0)return nums;
        int i=0,j=nums.length-1;
        while(true){
            while((nums[i]&1)!=0&&i<nums.length-1)i++;
            while(j>=0&&(nums[j]&1)==0)j--;
            if(i<j){
                int temp=nums[i];
                nums[i]=nums[j];
                nums[j]=temp;
            }
            else break;
        }
        return nums;
    }
}

双指针实现,注意数组越界问题。特殊情况,当输入数组全为奇数或者全为偶数时。

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

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

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

示例:

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

返回链表 4->5.

    public ListNode getKthFromEnd(ListNode head, int k) {
        int count=0;
        ListNode temp=head;
        while(temp!=null){
            count++;
            temp=temp.next;
        }
        int n=count-k;
        while(n>0){
            head=head.next;
            n--;
        }
        return head;
    }

思路二:不需要知道链表长度,指针1先走k-1步,然后指针2和指针1同时前进,当指针1指向链表最后一个元素时,指针2即为所求。

剑指 Offer 24. 反转链表

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

示例:

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

    public ListNode reverseList(ListNode head) {
        ListNode cur=head,pre=null,temp;
        while(cur!=null){
            temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }

注意结束条件的判断和双指针的使用

剑指 Offer 25. 合并两个排序的链表

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

示例1:

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

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode res=new ListNode(0),dum=res;
        while(l1!=null&&l2!=null)
        {
            if(l1.val<=l2.val){
                res.next=l1; 
                l1=l1.next;
            }
            else {
                res.next=l2;
                l2=l2.next;
            }
            res=res.next;
        }
        res.next=l1!=null?l1:l2;
        return dum.next;
    }

剑指 Offer 26. 树的子结构

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:
给定的树 A:

 3
/ \

4 5
/
1 2
给定的树 B:

4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:

输入:A = [3,4,5,1,2], B = [4,1]
输出:true

感觉树的很多递归题,想清楚如何分解为子问题就好做了,函数内调用递归函数不要太纠结细节,清楚函数的功能就行

    public boolean isSubStructure(TreeNode A, TreeNode B) {
        if(A==null||B==null)
            return false;
        return contains(A,B)||isSubStructure(A.left,B)||isSubStructure(A.right,B);
    }
    public boolean contains(TreeNode A,TreeNode B)
    {
        if(B==null)return true;
        if(A==null||A.val!=B.val)return false;
        return contains(A.left,B.left)&&contains(A.right,B.right);
    }

剑指 Offer 27. 二叉树的镜像

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

根据二叉树镜像的定义,考虑递归遍历(dfs)二叉树,交换每个节点的左 / 右子节点,即可生成二叉树的镜像。

    //递归
    public TreeNode mirrorTree(TreeNode root) {
        if(root==null)return null;
        TreeNode temp=root.left;
        root.left=mirrorTree(root.right);
        root.right=mirrorTree(temp);
        return root;
    }
    //使用辅助栈完成反转
    public TreeNode mirrorTree(TreeNode root) {
        if(root==null)return null;
        Stack<TreeNode> stack=new Stack<>();
        stack.add(root);
        while(stack.size()!=0){
            TreeNode a=stack.pop();
            if(a.left!=null)stack.push(a.left);
            if(a.right!=null)stack.push(a.right);
            TreeNode temp=a.left;
            a.left=a.right;
            a.right=temp;
        }
        return root;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值