剑指Offer(二)替换空格,从头到尾打印链表

题目:

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

例如输入"We are happy."

则输出"We%20are%20happy."

思路:

方法一,可以从头到尾扫描每个字符,遇到空格便把后面所有的字符向后移动,时间复杂度为O(n^2),暂不用

方法二,扫描一遍整个字符串,每有一个空格,都往字符串末尾添加两个任意字符,维护两个指针,指针a指向新建字符数组的最后一位,指针b指向原字符中的最后一个字符,逐个复制,b遇到空格时,使a先添加 % 20 这两个字符,当a,b指向同一个字符时,退出循环.

时间复杂度O(n)

方法三,新建一个队列,每次出队时判断是否为空格,如果是,添加"%20".  额外空间 O(n)

代码:

public static String replaceSpace(StringBuffer str) {
        int p1 = str.length()-1;
        for (int i = 0; i <=p1; i++)
        {
            if (str.charAt(i)==' ')
            {
                str.append(" ");
            }
        }
        int p2 = str.length()-1;
        //此时p2 指向新增空间后的字符串的最后一个位置
        while (p1!=p2)
        {
            if (str.charAt(p1)!=' ')
            {
                str.setCharAt(p2, str.charAt(p1));
                p1--;
                p2--;
            }
            else
            {
                p1--;
                str.setCharAt(p2--, '0');
                str.setCharAt(p2--, '2');
                str.setCharAt(p2--, '%');
            }
        }

        return str.toString();
    }

    public static void main(String[] args) {
        System.out.println(replaceSpace(new StringBuffer("we are happy.")));
    }

题目:

输入一个链表的头结点,从尾到头反过来打印出每个节点的值

思路:

方法一: 使用一个栈,依次压入,依次弹出,时间空间均为O(n)

方法二:递归,每次输出前,先输出他的下一个节点,然后依次调用.

方法三: 使用头插法,使用头插法去构建一个新的链表,这样最后的元素会在最前.

例子:

1 2 3 4 5  输出 5 4 3 2 1

代码:

    class ListNode {
        int val;
        ListNode next = null;
        ListNode(int val) {
           this.val = val;
        }
    }
    /**
     *但该方法若是输入的链表长度非常长时
     * 	  会导致函数调用的层级过深
     * 	  从而导致函数调用栈溢出(java.lang.StackOverflowError)
     */
    ArrayList<Integer> res=new ArrayList<Integer>();
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode!=null)
        {
            this.printListFromTailToHead(listNode.next);
            res.add(listNode.val);
        }
        return res;
    }

    /**
     * 调用栈
     * @param listNode
     * @return
     */
    public ArrayList<Integer> printListFromTailToHead2(ListNode listNode) {
        Stack<Integer> stack =new Stack<>();
        while(listNode!=null){
            stack.push(listNode.val);
            listNode=listNode.next;
        }
        ArrayList<Integer> list=new ArrayList<Integer>();
        while(!stack.isEmpty()){
            list.add(stack.pop());
        }
        return list;
    }


    /**
     * 使用头插法
     * 每次都是将 新的元素作为头节点,
     * 原链表中最后的节点就放到了最后,然后返回这个新的链表.
     * 注意点:
     * 	 * 头结点是在头插法中使用的一个额外节点,这个节点不存储值
     * 	 * 第一个节点就是链表的第一个真正存储值的节点
     */
    public ArrayList<Integer> printListFromTailToHead3(ListNode listNode) {
     ListNode head = new ListNode(-1);
     while (listNode!=null)
     {
         ListNode node =new ListNode(listNode.val);
         node.next = head.next;
         head.next = node;
         listNode = listNode.next;
     }
        ArrayList<Integer> res=new ArrayList<Integer>();
        head = head.next;
        while(head!=null)
        {
            res.add(head.val);
            head=head.next;
        }
        return res;
    }
发布了96 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41852212/article/details/100392840