剑指Offer(九)调整数组 链表倒数第k个节点

题目:

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

思路:

方法1

借用冒泡的思想,每两项比较,如果前偶后奇就交换。 复杂度为O(n^2)

方法2

空间换时间 ,新建一个数组,遍历给定数组,求出这个数组中的奇数的个数记作a,再遍历一遍数组,遇到奇数放a-1的前面,否则放后面。

方法3

插入排序的思想

代码:

    public void reOrderArray(int[] array)
    {
        for (int i = 0; i < array.length; i++)
        {
            for (int j = 0; j < array.length - i - 1; j++)
            {
                if (array[j] % 2 == 0 && array[j + 1] % 2 != 0)
                {
                    int a = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = a;
                }
            }
        }
    }

    public void reOrderArray1(int[] array)
    {
        int num = 0;
        for (int i = 0; i < array.length; i++)
        {
            if (array[i] % 2 == 1)
            {
                num++;
            }
        }
        int[] copy = array.clone();
        //克隆数组
        int a = 0;
        //分开计算位置   如果只用i 会出现重复赋值
        for (int i = 0; i < copy.length; i++)
        {
            if (copy[i] % 2 == 1)
            //奇
            {
                array[a++] = copy[i];
            }
            else
            {
                array[num] = copy[i];
                num++;
            }
        }
    }


    public void reOrderArray3(int[] array)
    {
        //相对位置不变,稳定性
        //插入排序的思想
        int m = array.length;
        int k = 0;//记录已经摆好位置的奇数的个数
        for (int i = 0; i < m; i++)
        {
            if (array[i] % 2 == 1)
            {
                int j = i;
                while (j > k)
                {//j >= k+1
                    int tmp = array[j];
                    array[j] = array[j - 1];
                    array[j - 1] = tmp;
                    j--;
                }
                k++;
            }
        }
    }

题目:

输入一个链表,输出该链表中倒数第k个结点。

思路:

方法1 遍历两遍链表,白给

方法2 建立栈,每次push一个节点,个数加一,当某个节点的next为空,push k个节点.

方法3

由于是倒数第k个,那么从最后一个节点到最后一个需要走 k-1 次

建立快慢指针,快指针先走 k-1 步,然后两个指针同时走,后一个指针的next 为空 ,前一个指针指向的节点就是目标节点.

例子:

1-2-3-4-5-6-7 求倒数第3 个,应该返回 5

快指针先走到了 3 ,那么当快指针到7,慢指针也就到了5

代码:

    //栈
    public ListNode FindKthToTail2(ListNode head, int k)
    {
        if (head == null || k == 0)
        {
            return null;
        }
        //可以先把链表反转,然后找出第k个
        Stack<ListNode> stack = new Stack<ListNode>();
        int count = 0;
        while (head != null)
        {
            stack.push(head);
            head = head.next;
            count++;
        }
        if (count < k)
        {
            return null;
        }
        int i = 0;
        ListNode node = null;
        while (i < k)
        {
            node = stack.pop();
            i++;
        }

        return node;
    
    }

    public ListNode FindKthToTail(ListNode head, int k)
    {
        if (head == null || k <= 0)
        {
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        for (int i = 1; i < k; i++)
        {
            if (fast.next == null)
            {
                return null;
            }
            fast = fast.next;
        }
        while (fast.next != null)
        {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
发布了96 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

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