以下算法题均来自LeetCode
1.两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
解题:
解题思路
此处撰写解题思路
代码
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
//循环 先确定一个数值,然后循环后一个数值
for(let i = 0;i<nums.length;i++){
// 固定一个值 然后往下依次循环
for(let j = i+1;j<nums.length;j++){
let sum = nums[i]+nums[j]
if(sum==target){
return [i,j]
}
}
}
};
2.两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
链接:https://leetcode-cn.com/problems/add-two-numbers
题解:开始也比较懵逼,参考了官方的一个答案,最后才看懂的
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
// 对链表中的每一位进行一一对应 使用链表去进行接收 用carry表示当前进位
// 1.如果链表1递归完 则链表2剩下的元素作为后面的值
// 2.如果链表2递归完 则链表1剩下的元素作为后面的值
//head节点作为新链表的链头 tail作为新链表的链尾,tail不断向后移动
var head = 0;
var tail = 0;
var carry = 0;
while(l1 || l2){
let n1 = l1?l1.val:0;
let n2 = l2?l2.val:0;
let sum = n1+n2+carry;
if(!head){
head = tail = new ListNode(sum%10);
}
else{
// tail不断向后移动
tail.next = new ListNode(sum%10);
tail = tail.next;
}
carry = Math.floor(sum / 10);
if(l1){
//移动链表
l1 = l1.next;
}
if(l2){
// 移动链表
l2 = l2.next;
}
}
//最后对carry进行判断,如果存在carry的话,则将carry加入到链表中
if(carry){
tail.next = new ListNode(carry);
tail = tail.next;
}
return head;
};
3.整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
题解:开始的时候,结果一直是0,最后参考官方答案知道需要使用~~将其转化为数值
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
let rev = 0;
while(x!=0){
// digit作为 当前数值的末尾数字
const digit = x%10;
// rev作为将末尾数值相应的倍数放入进去
rev = rev * 10 + digit;
// ~~ 利用符号进行的类型转换,转换成数字类型 还是原来的值
x=~~(x/10)
// 对rev进行判断
if (rev < Math.pow(-2, 31) || rev > Math.pow(2, 31) - 1) {
return 0;
}
}
return rev;
};
4.链表奇数位和偶数位的
题解:分别将奇数位和偶数位列出,形成新的链表,然后使用偶数位链表的头部连接奇数位的尾部
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
function oddEvenList( head ) {
// write code here
//查找链表的奇数节点、偶数节点 循环
// 将奇数放到一个链表中,偶数放到一个链表中,最后将偶数的头部连接再奇数链表的尾部
if(head == null){
return null;
}
//奇节点的尾部
var tail = head;
// 偶节点尾部
var l2 = head.next;
// 偶节点的头部
var l1 = l2;
while(l2 !=null && l2.next!=null){
tail.next = l2.next;
tail = tail.next;
l2.next = tail.next;
l2 = l2.next;
}
tail.next = l1;
return head;
}
oddEvenList();
module.exports = {
oddEvenList : oddEvenList
};
5.回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
链接:https://leetcode-cn.com/problems/palindrome-number
解题思路:
第一种,对数进行求余数和商,然后利用余数重新计算
第二种,利用高阶函数,split,reverse,join,将字符串转化为数组,再利用reverse函数,将数组逆序,然后再使用join函数将其转为字符串,与数值进行比较
/*
* @Author: your name
* @Date: 2021-11-01 18:59:38
* @LastEditTime: 2021-11-01 19:25:43
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \react\day04\回文数.js
*/
function isPalindrome(x) {
if((x<0 || x%10==0)&&x!=0){
return false;
}
// 第一种 对x每次除10 得到余数和商
// let mul = 0;
// let a = x;
// let b= 0;
// while(a!=0){
// b = x%10;
// mul = mul*10+b;
// a = a/10;
// }
// 第二种 可以将其转换成字符串,然后将字符串进行逆序 再比较原先字符串
if(x==0){
return true;
}
let str = x+"";
// 将字符串逆序排列
// return x;
let arr = str.split('').reverse().join('');
return arr===x;
};
console.log(isPalindrome(123));
6.罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
链接:https://leetcode-cn.com/problems/roman-to-integer
解题思路:一开始自己想的是直接使用switch,case,但是测试之后发现有一些需要枚举出来,然后就没啥思路了,只能参考被人写的代码,
第一种:将所有类型都列出来,放入对象中,然后循环遍历查找两个
第二种是将结果放入map中,也是判断如果字符串中前一个数值小于下一个字符串中字符的数值
// /**
// * @param {string} s
// * @return {number}
// */
// var romanToInt = function(s) {
// const map = {
// I : 1,
// IV: 4,
// V: 5,
// IX: 9,
// X: 10,
// XL: 40,
// L: 50,
// XC: 90,
// C: 100,
// CD: 400,
// D: 500,
// CM: 900,
// M: 1000
// };
// let ans = 0;
// for(let i = 0;i < s.length;) {
// if(i + 1 < s.length && map[s.substring(i, i+2)]) {
// ans += map[s.substring(i, i+2)];
// i += 2;
// } else {
// ans += map[s.substring(i, i+1)];
// i ++;
// }
// }
// return ans;
// };
var romanToInt = function(s) {
var hashNum = {
"I":1,
"V":5,
"X":10,
"L":50,
"C":100,
"D":500,
"M":1000
}
var result = 0;
for(let i = 0;i<s.length;i++){
hashNum[s[i]] < hashNum[s[i+1]] ? result -= hashNum[s[i]] : result += hashNum[s[i]]
}
return result;
};
7.最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
var longestCommonPrefix = function(strs) {
//思路
// 1.将第一个字符串作为最长的公共前缀
// 2.对数组中的每个字符串进行与公共前缀进行比较,得出新的公共前缀
// 3.如果数组比遍历完毕或者ans为“”,则返回
if(strs.length==0){
return ""
}
let prefix = strs[0];
for(let i = 1;i<strs.length;i++){
let j = 0;
for(;j<prefix.length && j<strs[i].length;j++){
// 判断前缀中的每一位是否与数组中字符串的每一位一一对应
if(prefix[j] !=strs[i][j]){
break;
}
}
// 进行比较后取出与前缀相同的字符串并重新赋值给前缀
prefix = prefix.substr(0,j);
if(prefix === ""){
return prefix
}
}
return prefix;
};