《算法通过村第二关---链表反转的拓展问题》

我们来讨论两个问题

1.指定区间反转

给定一个链表的头节点head,左值left的节点和右值right的节点,且left<=right。为此讨论两种方法:头插法和穿针引线法。

(1)头插法

当遍历到指定区间的第一个节点时,边遍历边插到区间的第一个位置。具体实现代码如下

    public static Node reverseList(Node head,int left,int right){
        Node dummyNode = new Node(-1);//建立头节点
        dummyNode.next = head;
        Node pre =dummyNode;
        //找到left的前一个位置
        for(int i = 0;i < left - 1;i++){
            pre = pre.next;
        }
        Node cur = pre.next;//待反转链表的头节点
        Node next;
        while (cur != null){
            next = cur.next;
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }
        return dummyNode.next;
    }

(2)穿针引线法

    public static Node reverseList(Node head,int left,int right){
        Node dummyNode = new Node(-1);
        Node pre = dummyNode;
        //找到left的前一个节点
        for (int i = 0;i < left - 1;i++){
            pre = pre.next;
        }
        Node rightNode = pre;
        //找到right的那个节点
        for (int i = 0;i < right - left +  1;i++){
            rightNode = rightNode.next;
        }
        Node ucc = rightNode.next;
        rightNode.next = null;//若不为null,则会在后面的reverse中误将right后面的节点也反转
        Node leftNode = pre.next;
        reverse(leftNode);
        pre.next = rightNode;//完成拼接
        leftNode.next = ucc;
        return dummyNode;
    }
    //具体反转操作的实现
    public static void reverse(Node head){
        Node pre = null;
        Node cur  = head;
        while (cur != null){
            Node next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
    }

2.两两交换节点

    public Node swapPairs(Node head){
        Node dummyHead = new Node(-1);
        dummyHead.next = head;
        Node temp = dummyHead;
        while(temp.next != null && temp.next.next != null){
            Node node1 = temp.next;
            Node node2 = temp.next.next;
            temp.next = node2;
            node1.next = node2.next;
            node2.next = node1;
            temp = node1;
        }
        return dummyHead.next;
    }

利用node1,node2,temp来完成两两交换。

接下来的内容可自行了解。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

LeetCode369.用一个非空链表来表示一个非负整数,完成+1操作。

例 head = {1,2,3}         ----->   head = {1,2,4}

思路:由于链表的操作是从表头开始的,所以得先反转过来。可以试一试栈。

具体代码实现如下。

    public Node plusOne (Node head){
        Stack<Node> st = new Stack<>();
        while (head != null ){
            st.push(head.val);
            head = head.next;
        }
        int carry = 0;
        int adder = 1;
        Node dummyNode = new Node(-1);
        while (!st.empty() && carry > 0){
            int digit = st.empty() ? 0 : st.pop().val;
            int sum = digit + adder + carry;
            carry = sum >= 10 ? 1 : 0;//判断是否要进位
            sum = sum >= 10 ? sum - 10 : sum;
            Node cur = new Node(sum);
            cur.next = dummyNode.next;
            dummyNode.next = cur;
            adder = 0;//后面还要计算十位百位,若不置为0,123会-->234
        }
        return dummyNode.next;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值