note_23:leetcode杂七杂八总结_1

leetcode杂七杂八总结_1


参考



1. 最长回文子串(longest palindromic substring)

题目

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Approach 4: Expand Around Center

  • 回文子串主要有两种样式,一种是"AbA",另一种是"AbbA"。这个方法是分开这两种形式来考虑的。遍历整个字符串,对于"AbA",以每个位置为中心点,然后向两边扩展,分别检测两边的字符是不是相同的,如果不相同的话就跳出循环;对于"AbbA",以每个位置以及它的下一个位置为中心点,也是向两边扩展,分别检测字符相不相同,如果不相同就跳出循环。在获取的两个子串长度中选择最长的那一个进行保存。
// js bin
function expand(s, left, right) {
  var str = s;
  var l = left; // 因为后面要加加减减,所以为了不改变传进来的值,就多开几个变量
  var r = right;
  while (l >= 0 && r < s.length) { // 从左右两边开始扩展,不能出界
    if (s[l] == s[r]) { // 或者用s.charAt(l) == s.charAt(r)
      l--;
      r++;
    } else {
      break;
    }
  }
  // 因为跳出来的时候不是越界就是不相等
  // 但是l已经多往左了一位,r也多往右了一位
  // 所以长度就是(r-1)-(l-1)+1 = r-l-1
  return r - l - 1; 
}

var longestPalindrome = function(s) {
  var maxLen = 0;
  var maxStr = "";
  for (var i = 0; i < s.length; i++) {
    var len1 = expand(s, i, i);
    var len2 = expand(s, i, i+1);
    var tempMax = Math.max(len1, len2);
    if (tempMax > maxLen) {
      maxLen = tempMax;
      // 如果是"AbA",那返回的长度肯定是个奇数
      // 如果是"AbbA",那返回的长度肯定是个偶数
      if (maxLen % 2 === 0) { 
        maxStr = s.substr(i+1-maxLen/2, maxLen);
      } else {
        maxStr = s.substr(i-(maxLen-1)/2, maxLen);
      }
    }
  }
  return maxStr;  // "aba"("bab"也是对的)
} ("babad");

console.log(longestPalindrome);

2. 单链表

不含头结点

// dev-c++
#include<iostream>

using namespace std;
typedef struct node {
	int data;
	struct node *next;
	node(int x):data(x),next(NULL) {
	}	
};

int main() {
	int arr[] = {1, 2, 3, 4, 5, 6};
	int size = sizeof(arr)/sizeof(arr[0]);
	
	// 打印有哪些点 
	cout << "点:" << arr[0];
	for (int i = 1; i < size; i++) {
		cout << " " << arr[i];
	}
	cout << endl;
	
	// 创建链表
	node *p = new node(arr[0]);
	node *head = p; // 不然等一下找不到头的位置 
	for (int i = 1; i < size; i++) {
		node *q = new node(arr[i]);
		p->next = q;
		p = p->next;
	}
	
	// 打印结果 
	p = head;
	cout << "打印链表:" << p->data;
	while (p->next != NULL) {
		p = p->next;
		cout << "->" << p->data;
	}
	cout << endl;
	
	// 查找结点 
	int target = 3; 
	cout << "目标点:" << target << "; ";
	
	p = head;
	int pos = -1;
	int count = 0;
	while (p != NULL) {
		if (p->data == target) {
			pos = count;
			break;
		} else {
			count++;
			p = p->next;
		}
	}
	if (pos == -1) cout << "不存在" << endl;
	else cout << "第" << pos << "位" << endl;
	
	// 改变结点的数据
	int targetPos = 4;
	int modiVal = 8;
	cout << "目标位置:" << targetPos << "; 值:" << modiVal << endl;
	if (targetPos < 0 || targetPos >= size) {
		cout << "非法位置" << endl;
	} else {
		count = 0;
		p = head;
		while (1) {
			if (count != targetPos) p = p->next;
			else break;
			count++;
		}
		p->data = modiVal;
	
		p = head;
		cout << "打印链表:" << p->data;
		while (p->next != NULL) {
			p = p->next;
			cout << "->" << p->data;
		}
		cout << endl;
	}
	
	// 插入结点 
	int insertPos = 2;
	int insertVal = 7;
	cout << "插入位置:" << insertPos << "; 插入值:" << insertVal << endl;
	if (insertPos < -1 || insertPos > size) {
		cout << "非法位置" << endl;
	} else {
		if (insertPos == -1) {
			node *q = new node(insertVal);
			q->next = head->next;
			head = q;
		} else if (insertPos = size) {
			node *q = new node(interVal);
			p = head;
			while (p->next != NULL) {
				p = p->next;
			}
			p->next = q;
		} else {
			count = 0;
			p = head;
			while (1) {
				if (count != insertPos - 1) p = p->next;
				else break;
				count++;
			}
			node *q = new node(insertVal);
			q->next = p->next;
			p->next = q;
		}
		size++;
		
		p = head;
		cout << "打印链表:" << p->data;
		while (p->next != NULL) {
			p = p->next;
			cout << "->" << p->data;
		}
		cout << endl;
	}
	
	// 删除结点
	int deletePos = 6; 
	cout << "删除位置:" << deletePos << endl;
	if (deletePos < 0 || deletePos > size - 1) {
		cout << "非法位置" << endl;
	} else {
		if (deletePos == 0) {
			node *q = head;
			head = head->next;
			delete q; 
		} else if (deletePos == size - 1) {
			p = head;
			while (p->next->next != NULL) {
				p = p->next;
			}
			node *q = p->next;
			p->next = NULL;
			delete q;
		} else {
			count = 0;
			p = head;
			while (1) {
				if (count != deletePos - 1) p = p->next;
				else break;
				count++;
			}
			node *q = p->next;
			p->next = p->next->next;
			delete q;
		}
		size--;
		
		p = head;
		cout << "打印链表:" << p->data;
		while (p->next != NULL) {
			p = p->next;
			cout << "->" << p->data;
		}
		cout << endl;
	}
	
	return 0; 
}

结果:
在这里插入图片描述


3. 数字转罗马数字

12. Integer to Roman

  • 一开始是直接建了数组用1,5,10,50,100,…
  • 因为是从大到小除下来的,然后发现到了9的位置,很麻烦。因为Math.floor(9/5) = 1,所以很容易出错。
  • 后来发现可以一开始就把数组变成1,4,5,9,10,40,50,90,100,…判断的时候没那么麻烦
// js bin
var intToRoman = function(num) {
  var symbol = ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'];
  var index = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000];
  var tempNum = num;
  var str = "";
  for (var i = index.length - 1; i >= 0; i--) {
    var temp =  Math.floor(tempNum / index[i]); // javascript的除法除不尽的话出来的是小数
//    console.log(temp);
    if (temp !== 0) {
        for (var j = 0; j < temp; j++) {
          str += symbol[i];
        }
      tempNum = tempNum - temp * index[i];
    }
  }
  return str;
} (1994);

console.log(intToRoman); // "MCMXCIV"

4. atoi

8. String to Integer (atoi)

分情况讨论:

  • 空字符串返回0。
  • 不要一上手就用stringstream,因为当字符串里有空格时,stringstream会返回0,程序结果就会返回0。
  • 先去掉开头的一些空格,找到第一个不是空格的数,然后将字符串剪出来。
  • 如果是空串就可以直接返回0了。
  • 如果第一位是+/-,那就从下一位开始遍历,遇到不是数字就停下,继续剪字符串。
  • 如果只有+/-或者还是空串,那就直接返回0。
  • 如果是数字,那要看看有没有超过INT_MAX和INT_MIN(头文件<limits.h>),如果就直接返回这两个中的一个,如果没有就直接返回数字。
// leetcode
#include<iostream>
#include<limits.h>
#include<string>
#include<sstream>

using namespace std;

class Solution {
public:
    int myAtoi(string str) {
        if (str == "") return 0;
        int pos = -1;
        for (int i = 0; i < str.length(); i++) {
            if (str[i] == ' ') pos = i;
            else break;
        }
        if (pos != -1) str = str.substr(pos+1, str.length()-1-pos);
        if (str == "") return 0;
        pos = -1;
        int start = 0;
        if (str[0] == '+' || str[0] == '-') start = 1;
        for (int i = start; i < str.length(); i++) {
            if (!(str[i] >= '0' && str[i] <= '9')) {
                pos = i;
                break;
            }
        }
        if (pos != -1) {
            str = str.substr(0, pos);
            if (str == "+" || str == "-" || str == "") return 0;
        }
        stringstream os;
        os << str;
        long result;
        os >> result;
        if (result > INT_MAX) return INT_MAX;
        if (result < INT_MIN) return INT_MIN;
        return result;
    }
};

如果数值很大:

  • 考虑用long、long int、double之类的
  • 如果是几个数要加在一起的话,可以考虑变成字符串,然后逐位加。设置一个变量记录进位。

stringstream:

  • 变量不要重复用,哪怕是接收同一个类型,转出同一个类型的,因为基本上都会出错。
  • 转换的时候有必要的话要判断是不是非数字:stringstream os,(os >> a)如果是非数会返回0。

5. 3 sum

15. 3Sum

因为我用的就是三重循环遍历数组,然后一直卡在最后两个案例过不了,系统显示Time Limited Exceed。后来,也改不出来了,所以就上网找了别的方法[LeetCode] 3Sum 三数之和

// leetcode
function sortNum(a, b) { // 必须要定义sort的排序方式,因为系统会按默认的排(不是由大到小也不是由小到大)
    return a - b; // 按从小到大排
}

var threeSum = function(nums) {
    if (nums.length === 0) return []; // 如果是空的话就直接返回
    nums.sort(sortNum); // 先排序,后面遍历的时候去重会方便很多
    if (nums[0] > 0 || nums[nums.length - 1] < 0) return []; // 因为要和为0,所以不能全正全负
    var arr = [];
    for (var i = 0; i < nums.length; i++) {
    	// 思路就是先定死一个数,让它小于或者等于0,然后找剩下两个数的和是定死数的相反数
        if (nums[i] > 0) break; 
        // 去重,因为后面找两数和的时候有考虑定死数的重复情况,所以这里要去掉
        if (i > 0 && nums[i] == nums[i - 1]) continue; 
        var fix = 0 - nums[i];
        var low = i + 1; // 左边限制
        var high = nums.length - 1; // 右边限制
        // 就是在剩下的元素中设置两个边界,在这个范围内找到两个数
        while (low < high) { // 不能取等号,因为一个元素不能被拿两次,除非它本身重复
            if (nums[low] + nums[high] == fix) {
                arr.push([nums[i], nums[low], nums[high]]);
                // 如果在左边重复了nums[low],左边界右移
                while (low < high && nums[low] == nums[low + 1]) ++low;
                // 如果在右边重复了nums[high],右边界左移
                while (low < high && nums[high] == nums[high - 1]) --high;
                // 因为上面两个while的比较条件都是和前一个或者后一个比
                // 所以最后边界还是会停在跟nums[low]相同的最右边和nums[high]相同的最左边
                // 所以low和high都要移位
                ++low;
                --high;
            } else if (nums[low] + nums[high] < fix) {
                ++low;
            } else {
                --high;
            }
        }
    }
    return arr;
};

Array对象的sort()方法

如果是排数字的话,一定要自己定义一个sortby()函数,因为它默认的排序方法不是按数字大小排的,尤其是掺了负数之后,排完之后既不是从大到小也不是从小到大。

// 按从小到大排序
function sortby(a, b) {
	return a - b;
}

6. 括号匹配和生成

Valid Parentheses
用栈,但是pop()之前要判断空不空,否则会出段错误。所有的容器都是。

#include<stack>

class Solution {
public:
    bool isValid(string s) {
        stack<char> pan;
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '(' || s[i] == '{' || s[i] == '[') {
                pan.push(s[i]);
            } else {
            // 要判断是否空,否则会出错
                if (pan.size() == 0) return false;
                char temp = pan.top();
                pan.pop();
                if (temp != '(' && s[i] == ')') return false;
                if (temp != '[' && s[i] == ']') return false;
                if (temp != '{' && s[i] == '}') return false;
            }
        }
        if (pan.size() != 0) return false;
        return true;
    }
};

22. Generate Parentheses,用递归生成配对的括号。重点在于最终结果是左边括号和右边括号相同,所以递归出口是左右都为0,因为每生成一个括号,对应的左右边会减1。

/**
 * @param {number} n
 * @return {string[]}
 */
function recursion(left, right, str, arr) {
  if (left > right) return; // 左括号比右括号多,非法串
  if (left === 0 && right === 0) arr.push(str); // 左右括号一样多,合法串
  if (left > 0) recursion(left-1, right, str+"(", arr);
  if (right > 0) recursion(left, right-1, str+")", arr);
}

var generateParenthesis = function(n) {
    var arr = [];
    var left = n;
    var right = n;
    var str = "";
    recursion(left, right, str, arr);
    return arr;
};

7. 链表的归并排序

如果是对数组用归并排序,那在进行merge()的时候要先申请一个跟输入数组大小一样的数组进行排序,所以空间复杂度是 O ( n ) O(n) O(n)
但是如果是对链表进行归并排序,就不需要额外申请一段跟链表大小一样的内存空间,只需要一个临时的ListNode *p

#include<iostream>

using namespace std;
typedef struct node {
	int data;
	struct node *next;
	node(int x):data(x),next(NULL) {
	}	
};

node* merge(node *left, node *right) {
	node *temp = new node(0);
	node *list = temp;
	while (left != NULL && right != NULL) {
		if (left->data <= right->data) {
			list->next = left;
			list = list->next;
			left = left->next;
		} else {
			list->next = right;
			list = list->next;
			right = right->next;
		}
	}
	if (left != NULL) list->next = left;
	if (right != NULL) list->next = right;
	list = temp->next;
	delete temp;
	return list; 
}

node* mergeSort(node *p) {
	if (p->next == NULL) return p;
	node *step = p;
	node *steps = p;
	node *prev = NULL;
	while (steps != NULL && steps->next != NULL) {
		steps = steps->next->next;
		prev = step;
		step = step->next;
	}
	prev->next = NULL;
	node *left = mergeSort(p);
	node *right = mergeSort(step);
	return merge(left, right);
}

node* sortList(node *p) {
	if (p == NULL || p->next == NULL) return p;
	return mergeSort(p);
}

int main() {
	int arr[] = {7, 10, 13, 16, 29, 32, 33, 37, 41, 43};
	int size = sizeof(arr)/sizeof(arr[0]);
	
	// 打印有哪些点 
	cout << "点:" << arr[0];
	for (int i = 1; i < size; i++) {
		cout << " " << arr[i];
	}
	cout << endl;
	
	// 创建链表
	node *p = new node(arr[0]);
	node *head = p; // 不然等一下找不到头的位置 
	for (int i = 1; i < size; i++) {
		node *q = new node(arr[i]);
		p->next = q;
		p = p->next;
	}
	
	// 打印结果 
	p = head;
	cout << "打印链表:" << p->data;
	while (p->next != NULL) {
		p = p->next;
		cout << "->" << p->data;
	}
	cout << endl;
	
	// 链表排序
	p = sortList(head);
	
	cout << "打印排好序的链表:" << p->data;
	p = p->next;
	while (p != NULL) {
		cout << "->" << p->data;
		p = p->next;
	}
	return 0; 
}

结果:
在这里插入图片描述


8. 全排列

31. Next Permutation,求字典序列的下一个排列
算法:字典序算法

从右到左找到第一个左边小于右边的数的位置,记为min(如果没有min,那么就说明序列已经按从大到小的顺序排列)
从右到左找到第一个大于位置min的数的位置,记为max
将min和max位置上的数对调
将min+1到结尾的数按从小到大排列

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
function sortby(a, b) {
    return a - b;
}
var nextPermutation = function(nums) {
    if (nums == null || nums.length == 1) return nums;
    var min = -1;
    // 从右到左找到第一个左边小于右边的数的位置,记为min
    for (var i = nums.length - 2; i >= 0; i--) {
        if (nums[i] < nums[i + 1]) {
            min = i;
            break;
        }
    }
    var max = -1;
    // 从右到左找到第一个大于nums[min]的数的位置,记为max
    for (var j = nums.length - 1; j >= 0; j--) {
        if (nums[j] > nums[min]) {
            max = j;
            break;
        }
    }
    // 所有数字都是右边比左边大,意味着按从大到小排列,是字典序的最后一个排列
    // 按照题目的意思,直接将最后一个排列的下一个排列换成由小到大排列
    if (min == -1) {
        nums.sort(sortby);
    } else {
    // 将min和max位置上的数字交换
        var temp = nums[min];
        nums[min] = nums[max];
        nums[max] = temp;
        // 将min+1到结尾的这一段序列按从小到大排列
        for (i = min + 1; i < nums.length - 1; i++) {
            var flag = false;
            for (j = nums.length - 1; j > i; j--) {
                if (nums[j] < nums[j - 1]) {
                    var tmp = nums[j];
                    nums[j] = nums[j - 1];
                    nums[j - 1] = tmp;
                    flag = true;
                }
            }
            if (!flag) break;
        }
    }
    return nums;
};

46. Permutations,求给定序列的全排列,LeetCode - 46. Permutations(三种方法)
可以用递归的方法来做,全排列就是从第一个数字起每个数分别与它后面的数字交换。dfs。

#include<iterator>
#include<vector>

class Solution {
public:
    // 交换函数,传引用是因为要直接操作原来的vector,而不是操作副本
    void swap(vector<int>& arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
    // 递归
    void permutation(vector<vector<int>>& result, vector<int>& nums, int start) {
    	// 换到最后一个位置的时候要停下来,把当前的排列取出
        if (start == nums.size()) {
            result.push_back(nums);
        } else {
        	// 从当前位置到末尾的所有可调换情况
            for (int i = start; i < nums.size(); i++) {
            	// 求全排列的关键在于数字交换
                swap(nums, start, i);
                // 继续求下一个排列
                permutation(result, nums, start + 1);
                // 每一个排列都是在原来的基础上进行交换,因为前面交换了,所以后面要换回来
                swap(nums, start, i);
            }
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> result;
        permutation(result, nums, 0);
        return result;
    }
};

47. Permutations II,和上面一题不同的地方在于给出的序列里面有重复的数字,如果直接沿用上面的方法,得出的排列会出现重复。

#include<algorithm>

class Solution {
public:
    void swap(vector<int>& arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
    void permutation(vector<vector<int>>& result, vector<int> nums, int start) {
        if (start == nums.size()) {
            result.push_back(nums);
            return;
        }
        // 排序是为了不重复调换跟当前数字一样的数字,防止重复
        sort(nums.begin() + start, nums.end());
        for (int i = start; i < nums.size();) {
            swap(nums, start, i);
            permutation(result, nums, start + 1);
            swap(nums, start, i);
            // 如果下一个数字跟当前要调换的数字一样,那么跳过下一个数字
            while (++i < nums.size() && nums[i] == nums[i - 1]);
        }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> result;
        permutation(result, nums, 0);
        return result;
    }
};

9. 二分法查找

33. Search in Rotated Sorted Array
由于整个序列是按照某个元素为中心进行旋转的,所以整个序列不一定是有序的。如果以0或者最后一位为枢轴进行旋转,那么序列有序;否则,就是分段有序。因此不能直接使用二分法,在使用之前要先判断是左边有序还是右边有序。

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    var low = 0;
    var high = nums.length - 1;
    var mid;
    // 二分法
    while (low <= high) {
        mid = Math.floor((low + high) / 2);
        if (nums[mid] == target) {
            return mid;
        }
        // 说明左边有序
        if (nums[mid] >= nums[low]) {
        // 一定要加上nums[low] <= target
        // 因为target小于中间值时有可能在左边(4567012,5),也可能在右边(23456701,0)
            if (nums[mid] >= target && nums[low] <= target) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        } else {
            if (nums[mid] <= target && nums[high] >= target) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
    }
    return -1;
};

34. Find First and Last Position of Element in Sorted Array
因为题目规定时间复杂度是 log ⁡ n \log n logn,所以优先考虑二分查找,要找到数字所在的位置范围,关键是先找到那个数字,然后分别往左边和右边扩展,与之前求回文字符串的方法相近。

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var searchRange = function(nums, target) {
    var low = 0;
    var high = nums.length - 1;
    var mid;
    var pos1;
    var pos2;
    while (low <= high) {
        mid = Math.floor((low + high) / 2);
        if (target == nums[mid]) {
            pos1 = pos2 = mid;
            while (pos1 >= 0 && target == nums[pos1]) pos1--;
            while (pos2 <= nums.length - 1 && target == nums[pos2]) pos2++;
            pos1++; // 上一步跳出循环的时候多移了一次
            pos2--; 
            return [pos1, pos2];
        } else if (target > nums[mid]) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    return [-1,-1];
};

10. 检测数独

36. Valid Sudoku
要检测三个地方:行、列、九宫格。检测行和列是很简单的两重循环,但是对比检测九宫格来说很难尽早检测出不合法的情况。但是每一个九宫格检测起来就很麻烦,因为一共有九个,每一个有九格。如果先检测九宫格是否合法,那么一旦不合法,后面的行列检测就不需要了。

/**
 * @param {character[][]} board
 * @return {boolean}
 */
var isValidSudoku = function(board) {
	// 用于统计
    var arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    // 数独有九个九宫格
    for (var k = 0; k < 3; k++) {
        for (var m = 0; m < 3; m++) {
            arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
            // 每个九宫格三行三列
            for (var i = 0; i < 3; i++) {
                for (var j = 0; j < 3; j++) {
                    if (board[i + 3 * k][j + 3 * m] != '.') {
                        arr[parseInt(board[i + 3 * k][j + 3 * m])]++;
                        if (arr[parseInt(board[i + 3 * k][j + 3 * m])] > 1) return false;
                    }
                }
            }
        }
    }
    // 检查行
    for (i = 0; i < 9; i++) {
        arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        for (j = 0; j < 9; j++) {
            if (board[i][j] != '.') {
                // 一边统计一边检查,可以马上排除不合法情况
                arr[parseInt(board[i][j])]++;
                if (arr[parseInt(board[i][j])] > 1) return false;
            }
        }
    }
    // 检查列
    for (j = 0; j < 9; j++) {
        arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        for (i = 0; i < 9; i++) {
            if (board[i][j] != '.') {
                arr[parseInt(board[i][j])]++;
                if (arr[parseInt(board[i][j])] > 1) return false;
            }
        }
    }
    return true;
};

11. 大数乘法

43. Multiply Strings
直接将两个数字相乘是不可能的,因为肯定会有溢出的样例。直接操作字符串空闲复杂度会低一点,但是如果是用javascript来写就很不方便,因为javascript的string对象是不能直接更改其中的某一个元素的,所以可以将字符串转化成一个元素类型为number的数组。

模拟手动算多位数乘法的方法来计算两个数相乘,逐位相乘相加。初始的两个字符串可以不reverse,只要后面计算结果的时候reverse就可以了。

0乘任何数都为0,可以把这种情况单独拿出来。

/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */

var multiply = function(num1, num2) {
	// 0乘任何数为0
    if (num1 == "0" || num2 =="0") return "0";
    // result存储的时候是反过来的,所以最后要翻转一次
    var result = [];
    var len1 = num1.length;
    var len2 = num2.length;
    var up = [], down = [];
    for (var i = 0; i < len1; i++) {
      up.push(parseInt(num1[i]));
    }
    for (var j = 0; j < len2; j++) {
      down.push(parseInt(num2[j]));
    }
    // 逐位相乘相加
    for (i = 0; i < len2; i++) {
        for (j = 0; j < len1; j++) {
            var temp = down[len2 - i - 1] * up[len1 - j - 1];
            var midresult;
            // 判断上一步有没有进位
            if (result[j + i] !== undefined) {
              midresult = result[i + j] + temp;
              // 进位留到下一个位置算
              result[i + j] = (result[i + j] + temp) % 10;
            } else {
              midresult = temp;
              result[i + j] = temp % 10;
            }
            // 判断这一步有没有进位
            if (result[i + j + 1] !== undefined) {
            // 当前进位加上下一个位置上的数
              result[i + j + 1] = result[i + j + 1] + Math.floor(midresult / 10);
            } else {
              result[i + j + 1] = Math.floor(midresult / 10);
            }
        }
    }
    // 因为最后返回的结果字符串开头没有0,所以要把反过来的result结尾的0全部去掉
    i = result.length - 1;
    while (result.length !== 0) {
        if (result[i] === 0) result.pop();
        else break;
        i--;
    }
    reresult = result.reverse().join("");
    return reresult;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值