• 编码技巧之循环【笔记】


    编码技巧之循环【笔记】

    循环控制

    在循环中要定义一个循环不变式

    循环不变式是一句断言定义各变量所满足的条件

    与递归不同,在递归里面断言就是证明一个函数,而在循环中,是没法直接看到的,是心中默认的一个条件

    循环的书写方法

    定义一个循环不变式,并在循环体每次结束后保持循环不变式

    和递归一样,先一般情况,然后再特殊情况

    每次必须向前推进循环不变式中涉及的变量值,且每次推进的规模不能多,必须为1

    例题一:链表反转

    将1->2->3->4->5->null变成null<-1<-2<-3<-4<-5

    与递归的想法不同,循环的话不能将第一个单独提出来,因为这样要考虑很多的边界问题,因此可以在链表中间切一刀,将前三个反转以后可以发现就是头和尾变化了,此时可以设置两个变量来维持

    其中newhead指向反转成功的链表,currenthead指向还没有成功反转的链表,这就是循环不变式,每次循环都必须遵守,推进以后

    只要当newhead从null移动到5的时候,currenthead移动到null的时候,就可以确定整个链表反转完成了

    具体代码如下:

    package interview.loop;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    import interview.common.Node;
    import interview.recursion.LinkedListCreator;
    
    public class LinkedListReverser {
    
      public <T> Node<T> reverseLinkedList(Node<T> head) {
        Node<T> newHead = null;
        Node<T> curHead = head;
        // Loop invariant:
        // newHead points to the linked list already reversed.
        // curHead points to the linked list not yet reversed.
    
        // Loop invariant holds.
        while(curHead != null) {
          // Loop invariant holds.
          Node<T> next = curHead.getNext();
          curHead.setNext(newHead);
          newHead = curHead;
          curHead = next;
          // Loop invariant holds.
        }
        // Loop invariant holds.
        return newHead;
      }
    
      public static void main(String[] args) {
        LinkedListCreator creator = new LinkedListCreator();
        LinkedListReverser reverser = new LinkedListReverser();
    
        Node.printLinkedList(reverser.reverseLinkedList(
            creator.createLinkedList(new ArrayList<>())));
    
        Node.printLinkedList(reverser.reverseLinkedList(
            creator.createLinkedList(Arrays.asList(1))));
    
        Node.printLinkedList(reverser.reverseLinkedList(
            creator.createLinkedList(Arrays.asList(1, 2, 3, 4, 5))));
        System.out.println("done");
      }
    }
    

    例题二:链表中的节点删除(delete_if)

    将1->2->3->2->5->null中的所有数值为2的节点全部删除,删除以后变为1->3->5->null

    设置一个变量previous指向对应的节点,在删除后面的节点以后previous不需要移动,不然在遇到两个连续的需要删除的节点的时候会错过一个

    循环不变式是要保证所有的数值为2的节点能够被正确的删除

    如果头结点没有previous怎么办?

    进行特殊处理或者增加虚拟的头结点

    具体代码如下:

    package interview.loop;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    import interview.common.Node;
    import interview.recursion.LinkedListCreator;
    
    public class LinkedListDeletor {
    
      public <T> Node<T> deleteIfEquals(Node<T> head, T value) {
        while (head != null && head.getValue() == value) {
          head = head.getNext();
        }
    
        if (head == null) {
          return null;
        }
    
        Node<T> prev = head;
        // Loop invariant: list nodes from head up to prev has been
        // processed. (Nodes with values equal to value are deleted.)
        while(prev.getNext() != null) {
          if (prev.getNext().getValue() == value) {
            // delete it
            prev.setNext(prev.getNext().getNext());
          } else {
            prev = prev.getNext();
          }
        }
    
        return head;
      }
    
      public static void main(String[] args) {
        LinkedListCreator creator = new LinkedListCreator();
        LinkedListDeletor deletor = new LinkedListDeletor();
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1, 2, 3, 2, 5)),
            2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1, 2, 3, 2, 2)),
            2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(1, 2, 3, 2, 2)),
            1));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 2, 3, 2, 2)),
            2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2, 2, 2, 2, 2)),
            2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2)),
            2));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(Arrays.asList(2)),
            1));
        Node.printLinkedList(deletor.deleteIfEquals(
            creator.createLinkedList(new ArrayList<Integer>()),
            1));
      }
    }
    

    感谢观看,文笔有限,博客不出彩,还请多多见谅
  • 相关阅读:
    团队项目总结
    第二阶段团队绩效评分
    “转赚”------使用说明
    团队站立会议14
    团队站立会议13
    团队站立会议12
    团队站立会议11
    团队站立会议10
    LocalDate 今天是一年中的第几天?
    MAC系统Java环境搭建
  • 原文地址:https://www.cnblogs.com/jokingremarks/p/14468515.html
Copyright © 2020-2023  润新知