class Solution {    class ListNode{        int value;        ListNode next;        public ListNode(int value, ListNode next) {            this.value = value;            this.next = next;        }        public ListNode(int value) {            this.value = value;        }        public ListNode() {        }    }    public ListNode reverseKGroup(ListNode head, int k) {        //使用栈来保存节点        Stack<ListNode>stack=new Stack<>();        //设置虚拟节点        ListNode virtualNode=new ListNode(0);        ListNode dummy=virtualNode;        ListNode temp=head;        while (true){            int count=0;            //往栈中压入k个节点            while (temp!=null&&count<k){                stack.push(temp);                temp=temp.next;                count++;            }            //如果count!=k,那就把虚拟节点的next指向指向头结点            if(count!=k){                dummy.next=head;                break;//这里必须要退出            }            //如果count==k,那就建链表            while (!stack.isEmpty()){                dummy.next=stack.pop();                dummy=dummy.next;            }            //将新节点的next指向指向temp节点            dummy.next=temp;            //前面k组已经反转完,所以需要把头节点设置为temp            head=temp;        }        return virtualNode.next;    }}
public ListNode reverseBetween(ListNode head, int left, int right) {        if(left==right){            return head;        }        ListNode virtualNode = new ListNode(0);        virtualNode.next=head;        //1.先找到反转链表的起始节点的前置节点和末尾节点        //前置节点        ListNode pre=virtualNode;        //末尾节点        ListNode end=virtualNode;        for(int i=0;i<left-1;i++){            pre=pre.next;            end=end.next;        }        for(int i=0;i<right-left+1;i++){            end=end.next;        }        //当前反转的起始节点        ListNode cur=pre.next;        //当前反转末尾节点的下一个节点        ListNode curr=end.next;        //2.切断链表        pre.next=null;        end.next=null;        //3.反转这中间的链表        ListNode node = reverse(cur);        //4.搭接链表        pre.next=node;        cur.next=curr;        return virtualNode.next;    }    private ListNode reverse(ListNode head){        ListNode pre=null;        ListNode cur=head;        //3.反转这中间的链表        while (cur!=null){            ListNode next=cur.next;            cur.next=pre;            pre=cur;            cur=next;        }        return pre;    }
public ListNode deleteDuplicates(ListNode head) {        ListNode virtualNode = new ListNode(0);        ListNode temp = virtualNode;        while (head != null) {            //如果head已到末尾节点,或者当前节点有效            if (head.next == null || head.val != head.next.val) {                temp.next = head;                temp = temp.next;            }            //如果当前节点与下一节点重复            while (head.next != null && head.val == head.next.val) {                //就一直跳过重复节点                head = head.next;            }            head = head.next;        }        temp.next = null;        return virtualNode.next;    }
public int firstMissingPositive(int[] nums) {        int n=nums.length;        for(int i=0;i<n;i++){            //nums[i]应该存放在i-1的位置上            while (nums[i]>=1&&nums[i]<=n&&nums[i]!=nums[nums[i]-1]){                swap(nums,i,nums[i]-1);            }        }        for(int i=0;i<n;i++){            if(nums[i]!=i+1){                return i+1;            }        }        return n+1;    }    private void swap(int []nums,int left,int right){        int temp=nums[right];        nums[right]=nums[left];        nums[left]=temp;        return;    }
    List<String> res = new ArrayList<>();    Deque<String> path = new ArrayDeque<>(4);    public List<String> restoreIpAddresses(String s) {        if (s == null || s.length() <= 3 || s.length() > 12) {            return res;        }        int len = s.length();        backTrack(s, len, 0, 4);        return res;    }    //restSeg变量用来表示还有多少段没有被分割    private void backTrack(String str, int len, int begin, int restSeg) {        //如果已经遍历到末尾了        if (begin == len) {            //并且所有段都已被分割            if (restSeg == 0) {                res.add(String.join(".", path));            }            //只要遍历到末尾就返回            return;        }        //每段最多为取3位        for (int i = begin; i < begin + 3; i++) {            if (i >= len) {                break;            }            //如果剩下的数字无法被完全3位数分割            if (restSeg * 3 < len - i) {                continue;            }            if (check(str, begin, i)) {                String segment = str.substring(begin, i + 1);                path.addLast(segment);                backTrack(str, len, i + 1, restSeg - 1);                path.removeLast();            }        }    }    private boolean check(String str, int left, int right) {        int len = right - left + 1;        //如果是01这种就不行        if (len > 1 && str.charAt(left) == '0') {            return false;        }        int res = 0;        while (left <= right) {            res = res * 10 + (str.charAt(left) - '0');            left++;        }        return res >= 0 && res <= 255;    }
public String multiply(String num1, String num2) {  if(num1.equals("0")||num2.equals("0")){    return "0";  }  char[] chars1 = num1.toCharArray();  char[] chars2 = num2.toCharArray();  //预分配空间,存储运算结果  int[] temp = new int[num1.length() + num2.length()];  //先不考虑进位问题,先将结果存放于临时数组中,把index=0的位置空出来,用于存放进位  for (int i = 0; i < chars1.length; i++) {    for (int j = 0; j < chars2.length; j++) {      temp[i + j + 1] += (chars1[i] - '0') * (chars2[j] - '0');    }  }  //从后往前进行进位处理  for (int i = temp.length - 1; i > 0; i--) {    if (temp[i] >= 10) {      //打个比方,如果是25,那temp[i]就变成5,让前置位+2      temp[i - 1] += temp[i] / 10;      temp[i] %= 10;    }  }  StringBuilder res = new StringBuilder();  for (int i : temp) {    res.append(i);  }  //如果前置位是0的话,就需要去掉0  if (res.charAt(0) == '0') {    res.deleteCharAt(0);  }  return res.toString();    }
String[] ver1 = version1.split("\\.");String[] ver2 = version2.split("\\.");int max = Math.max(ver1.length, ver2.length);for (int i = 0; i < max; i++) {  int nums1;  int nums2;  if (i >= ver1.length) {    nums1 = 0;  } else {    nums1 = Integer.parseInt(ver1[i]);  }  if (i >= ver2.length) {    nums2 = 0;  } else {    nums2 = Integer.parseInt(ver2[i]);  }  if (nums1 == nums2) {    continue;    //此时version1>version2  } else if (nums1 > nums2) {    return 1;  } else {    return -1;  }}return 0;
//rand7()-1可以获取0、1、2、3、4、5、6//*7后可以获取到0、7、14、21、28、35、42//再加7可以获取到1、2、3、4、5、6、7//然后再把二者相加获取1-10的数据int num = (rand7() - 1) * 7 + rand7();//如果当前数据>10,需要按照这个算法再次获取while (num > 10) {  num = (rand7() - 1) * 7 + rand7();}return num;
public int widthOfBinaryTree(TreeNode root) {  Deque<TreeNode> queue = new LinkedList<>();  Deque<Integer> numQueue = new LinkedList<>();  queue.addLast(root);  numQueue.addLast(1);  while (!queue.isEmpty()) {    int size = queue.size();    int left = -1;    int right = -1;    int tempWidth = 0;    for (int i = 0; i < size; i++) {      TreeNode node = queue.pollFirst();      int position = numQueue.pollFirst();      if (i == 0) {        left = position;      }      if (i == size - 1) {        right = position;      }      if (node.left != null) {        queue.addLast(node.left);        numQueue.addLast(position * 2);      }      if (node.right != null) {        queue.addLast(node.right);        numQueue.addLast(position * 2 + 1);      }    }    tempWidth = right - left + 1;    res = Math.max(res, tempWidth);  }  return res;}
Stack<Integer> stack = new Stack<>();char[] chars = s.toCharArray();int index = 0;while (index < chars.length) {  //如果是空格的话就直接跳过  if (chars[index] == ' ') {    index++;    continue;  }  char temp = chars[index];  //如果是加减乘除的话,如果后面有空格就一直++,直到不是空格  if (temp == '+' || temp == '-' || temp == '*' || temp == '/') {    index++;    while (index < chars.length && chars[index] == ' ') {      index++;    }  }  int num = 0;  while (index < chars.length && Character.isDigit(chars[index])) {    num = num * 10 + (chars[index++] - '0');  }  if (temp == '-') {    num = -num;  } else if (temp == '*') {    num = stack.pop() * num;  } else if (temp == '/') {    num = stack.pop() / num;  }  stack.push(num);}int res = 0;while (!stack.isEmpty()) {  res += stack.pop();}return res;
int m = mat.length;int n = mat[0].length;int[] res = new int[m * n];int row = 0;int col = 0;for (int i = 0; i < res.length; i++) {  res[i] = mat[row][col];  //如果row+col%2==0的话,那就按右上方向走  if ((row + col) % 2 == 0) {    //如果列已到达最后一列,就需要往下走一格,否则会越界    if (col == mat[0].length - 1) {      row++;      //如果行的坐标是0的话,就往右走一格    } else if (row == 0) {      col++;    } else {      //其他情况,按照右上走      row--;      col++;    }    //如果row+col%2==1的话,那就按左下方向走  } else {    //如果行已到最后一行,就必须往右走了,否则会越界    if (row == mat.length - 1) {      col++;      //如果列的坐标是0的话,就往右走一格    } else if (col == 0) {      row++;    } else {      //其他情况,按照左下走      row++;      col--;    }  }}return res;
public String removeKdigits(String num, int k) {        char[] chars = num.toCharArray();        if (chars.length <= k) {            return "0";        }        //维护一个单调不下降的队列        Deque<Character>queue=new LinkedList<>();        for (int i = 0; i < chars.length; i++) {            char ch = chars[i];            //如果当前元素大于队列尾元素并且k>0,就弹出队列尾部元素            while (k > 0 && !queue.isEmpty() && ch < queue.peekLast()) {                k--;                queue.pollLast();            }            //如果是0123这种情况,0就不需要添加            if (i == 0 && ch == '0') {                continue;            //其他情况,加入队列中            } else {                queue.addLast(ch);            }        }        //如果此时k还大于0的话;比如123,k=1这种情况,那就需要弹出尾部元素        while (k>0&&!queue.isEmpty()){            queue.pollLast();            k--;        }        StringBuilder res = new StringBuilder();        //设置一个布尔标记为,如果队列首元素是0的话就continue        boolean flag=true;        while (!queue.isEmpty()) {            Character ch = queue.pollFirst();            if(flag&&ch=='0'){                continue;            }            flag=false;            res.append(ch);        }        if(res.length()==0){            return "0";        }        return res.toString();    }