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(); }