剑指 Offer 09. 用两个栈实现队列

问题:只是删除时候返回了头节点,那怎么拿到这个queue呢

  1. // 栈的特性是后进先出
  2. // 队列的特性是先进先出
  3. // 每次操作返回状态,如果没元素返回-1
  4. var CQueue = function() {
  5. this.inStack = []
  6. this.outStack = []
  7. };
  8. /**
  9. * @param {number} value
  10. * @return {void}
  11. */
  12. CQueue.prototype.appendTail = function(value) {
  13. this.inStack.push(value)
  14. };
  15. /**
  16. * @return {number}
  17. */
  18. CQueue.prototype.deleteHead = function() {
  19. if (!this.outStack.length) {
  20. if (!this.inStack.length) {
  21. return -1
  22. }
  23. this.in2out()
  24. }
  25. return this.outStack.pop()
  26. };
  27. CQueue.prototype.in2out = function() {
  28. while(this.inStack.length) {
  29. this.outStack.push(this.inStack.pop())
  30. }
  31. }
  32. /**
  33. * Your CQueue object will be instantiated and called as such:
  34. * var obj = new CQueue()
  35. * obj.appendTail(value)
  36. * var param_2 = obj.deleteHead()
  37. */

207. 课程表

273. 整数转换英文表示

  1. /**
  2. * @param {number} num
  3. * @return {string}
  4. */
  5. const nt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
  6. "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"],
  7. tens = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"],
  8. bmt = ["Billion","Million","Thousand"],
  9. BILLION = 1000000000, MILLION = 1000000, THOUSAND = 1000;
  10. var num2str = function(num) {
  11. const ans = [];
  12. if(num >= 100){
  13. ans.push(nt[Math.floor(num/100)]);
  14. ans.push("Hundred");
  15. num %= 100;
  16. }
  17. if(num >= 20){
  18. ans.push(tens[Math.floor(num/10)]);
  19. num %= 10;
  20. }
  21. if(num > 0){
  22. ans.push(nt[num]);
  23. }
  24. return ans.join(" ");
  25. }
  26. var numberToWords = function(num) {
  27. if(num == 0)
  28. return nt[num];
  29. const res = [];
  30. if(num >= BILLION){
  31. res.push(num2str(Math.floor(num/BILLION)));
  32. res.push(bmt[0]);
  33. num %= BILLION;
  34. }
  35. if(num >= MILLION){
  36. res.push(num2str(Math.floor(num/MILLION)));
  37. res.push(bmt[1]);
  38. num %= MILLION;
  39. }
  40. if(num >= THOUSAND){
  41. res.push(num2str(Math.floor(num/THOUSAND)));
  42. res.push(bmt[2]);
  43. num %= THOUSAND;
  44. }
  45. if(num > 0)
  46. res.push(num2str(num));
  47. return res.join(" ");
  48. };

7. 整数反转

var reverse = function(x) {
    let res = 0;
    while(x){
        res = res * 10 + x % 10;
        if(res > Math.pow(2, 31) - 1 || res < Math.pow(-2, 31)) return 0;
        // 相当于 parseInt
        x = ~~(x / 10);
    }
    return res;
};

复原IP地址

const restoreIpAddresses = (s) => { 
  const res = [];
  // 复原从start开始的子串
  const dfs = (subRes, start) => {                 
    if (subRes.length == 4 && start == s.length) { // 片段满4段,且耗尽所有字符
      res.push(subRes.join('.'));                  // 拼成字符串,加入解集
      return;                     // 返不返回都行,指针已经到头了,严谨的说还是返回
    }
    // 这里为什么return不push
    if (subRes.length == 4 && start < s.length) {  // 满4段,字符未耗尽,不用往下选了
      return;
    }
    for (let len = 1; len <= 3; len++) {           // 枚举出选择,三种切割长度
      if (start + len - 1 >= s.length) return;     // 加上要切的长度就越界,不能切这个长度
      if (len != 1 && s[start] == '0') return;     // 不能切出'0x'、'0xx'

      const str = s.substring(start, start + len); // 当前选择切出的片段
      if (len == 3 && +str > 255) return;          // 不能超过255

      subRes.push(str);                            // 作出选择,将片段加入subRes
      dfs(subRes, start + len);                    // 基于当前选择,继续选择,注意更新指针
      // 为什么是撤销
      subRes.pop(); // 上面一句的递归分支结束,撤销最后的选择,进入下一轮迭代,考察下一个切割长度
    }
  };

  dfs([], 0);       // dfs入口
  return res;
};

31. 下一个排列

思路:

function nextPermutation(nums) {
    let i = nums.length - 2;                   // 向左遍历,i从倒数第二开始是为了nums[i+1]要存在
    while (i >= 0 && nums[i] >= nums[i + 1]) { // 寻找第一个小于右邻居的数
        i--;
    }
    if (i >= 0) {                             // 这个数在数组中存在,从它身后挑一个数,和它换
        let j = nums.length - 1;                // 从最后一项,向左遍历
        while (j >= 0 && nums[j] <= nums[i]) {  // 寻找第一个大于 nums[i] 的数
            j--;
        }
        [nums[i], nums[j]] = [nums[j], nums[i]]; // 两数交换,实现变大
    }
    // 如果 i = -1,说明是递减排列,如 3 2 1,没有下一排列,直接翻转为最小排列:1 2 3
    let l = i + 1;           
    let r = nums.length - 1;
    while (l < r) {                            // i 右边的数进行翻转,使得变大的幅度小一些
        [nums[l], nums[r]] = [nums[r], nums[l]];
        l++;
        r--;
    }
}