每周算法4

2020.10.06

1.Z字形变换

  • 这道题主要是找字符串每个字符i所对应的索引与最后输出的索引之间的规律
/**
 * @param {string} s
 * @param {number} numRows
 * @return {string}
 */
var convert = function(s, numRows) {
  if(numRows==1){
    return s
  }
  let res=[]
  for(let i=0;i<numRows;i++){
    res[i]=""
  }
  let index,x
  for(let i=0;i<s.length;i++){
    index = i%(numRows+numRows-2)
    if(index<numRows){
      res[index]+=s[i]
    }else{
      x = numRows-1-(i-((numRows-1)*(Math.floor(i/(numRows-1)))))
      res[x]+=s[i]
    }
  }
  return res.join("")
};

2.整数转罗马数字

  • 现将输入数字的每一位数字提取到nums数组中
  • 然后考虑数组中每个数字对应的罗马数字(例如:[1,2,3] ==> 100:C,20:XX,3:III)
/**
 * @param {number} num
 * @return {string}
 */
var intToRoman = function (num) {
  let nums = []
  let res = ""
  while (num) {
    nums.unshift(num % 10)
    num = Math.floor(num / 10)
  }
  for (let i = 0; i < nums.length; i++) {
    let k = nums.length - i - 1
    if (k == 3) {
      for (let j = 0; j < nums[i]; j++) {
        res += "M"
      }
    } else if (k == 2) {
      if(nums[i]==5){
        res+="D"
      }
      if(nums[i]==4){
        res+="CD"
      }
      if(nums[i]==9){
        res+="CM"
      }
      if(nums[i]<5&&nums[i]!=4){
        for(let j=0;j<nums[i];j++){
          res+="C"
        }
      }
      if(nums[i]>5&&nums[i]!=9){
        res+="D"
        for(let j=0;j<nums[i]-5;j++){
          res+="C"
        }
      }
    } else if (k == 1) {
      if(nums[i]==5){
        res+="L"
      }
      if(nums[i]==4){
        res+="XL"
      }
      if(nums[i]==9){
        res+="XC"
      }
      if(nums[i]<5&&nums[i]!=4){
        for(let j=0;j<nums[i];j++){
          res+="X"
        }
      }
      if(nums[i]>5&&nums[i]!=9){
        res+="L"
        for(let j=0;j<nums[i]-5;j++){
          res+="X"
        }
      }
    } else if (k == 0) {
      if(nums[i]==5){
        res+="V"
      }
      if(nums[i]==4){
        res+="IV"
      }
      if(nums[i]==9){
        res+="IX"
      }
      if(nums[i]<5&&nums[i]!=4){
        for(let j=0;j<nums[i];j++){
          res+="I"
        }
      }
      if(nums[i]>5&&nums[i]!=9){
        res+="V"
        for(let j=0;j<nums[i]-5;j++){
          res+="I"
        }
      }
    }
  }
  return res
};
2020.10.07

1.有效的字母异位词

  • 将s, t字符串排序,判断排完序之后的字符串是否相等
/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var isAnagram = function(s, t) {
  if(s.length!=t.length){
    return false
  }
  let sArr = s.split("").sort()
  let tArr = t.split("").sort()
  return sArr.toString()==tArr.toString()
};

2.字母异位词分组

  • 将输入的数组进行排序
  • 遍历数组,看第i个字母是否与剩下的字母是否是字母异位词,如果满足,将满足的字符添加到res[i]中,并将满足的字母赋值为“*”
/**
 * @param {string[]} strs
 * @return {string[][]}
 */
var groupAnagrams = function(strs) {
  let res = []
  let arr=[]
  strs.sort()
  for(let i=0;i<strs.length;i++){
    arr[i] = strs[i].split("").sort().join("")
  }
  for(let i=0;i<arr.length;i++){
    res[i]=[]
    if(arr[i]!="*"){
      res[i].push(strs[i])
    }
    for(let j=i+1;j<arr.length;j++){
      if(arr[i]==arr[j]&&arr[j]!="*"){
        res[i].push(strs[j])
        arr[j] = "*"
      }
    }
  }
  for(let i=0;i<res.length;i++){
    if(res[i].length==0){
      res.splice(i,1)
      i--
    }
  }
  return res
};

3.字符串相乘

  • 使用下面的代码会出现错误,当"123456789"*“987654321"时会输出"121932631112635260"而不是"121932631112635269”,因为js最大的数为Number.MAX_SAFE_INTEGER
/**
 * @param {string} num1
 * @param {string} num2
 * @return {string}
 */
var multiply = function (num1, num2) {
  let arr1 = num1.split("") 
  let arr2 = num2.split("")
  let len1 = arr1.length
  let len2 = arr2.length
  let t = 0,
    sum
  let res = [],
    resNum = 0
  for (let i = len2 - 1; i >= 0; i--) {
    t = 0
    res[i] = 0
    for (let j = len1 - 1; j >= 0; j--) {
      sum = (arr2[i] - '0') * (arr1[j] - '0') + t
      t = Math.floor(sum / 10) 
      res[i] += (sum % 10) * Math.pow(10, len1 - j - 1)
      if (j == 0 && t != 0) {
        res[i] += t * Math.pow(10, len1)
      }
    }
  }
  // console.log(res)
  for (let i = 0; i < res.length; i++) {
    // console.log(resNum,res[i] * Math.pow(10, res.length - i -1))
    resNum += res[i] * Math.pow(10, res.length - i -1)
  }
  return resNum + ''
};
  • 所以将代码改为下面的形式
const multiply = (num1, num2) => {
  const len1 = num1.length;
  const len2 = num2.length;
  const pos = new Array(len1 + len2).fill(0);

  for (let i = len1 - 1; i >= 0; i--) {
    const n1 = +num1[i];
    for (let j = len2 - 1; j >= 0; j--) {
      const n2 = +num2[j];
      const multi = n1 * n2;             
      const sum = pos[i + j + 1] + multi; 

      pos[i + j + 1] = sum % 10;
      pos[i + j] += sum / 10 | 0;
    }
  }
  while (pos[0] == 0) {
    pos.shift();
  }
  return pos.length ? pos.join('') : '0';
};
2020.10.08

1.两个数组的交集

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function(nums1, nums2) {
  return Array.from(new Set([...nums1].filter(x=>nums2.includes(x))))
};

2.两个数组的交集Ⅱ

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
  nums1.sort((a,b)=>a-b)
  nums2.sort((a,b)=>a-b)
  let L=0,R=0
  let res = []
  while(L<nums1.length&&R<nums2.length){
    if(nums1[L]==nums2[R]){
      res.push(nums1[L])
      L++
      R++
    }
    else if(nums1[L]<nums2[R]){
      L++
    }else if(nums1[L]>nums2[R]){
      R++
    }
  }
  return res
};

3.合并区间

/**
 * @param {number[][]} intervals
 * @return {number[][]}
 */
var merge = function (intervals) {
  if(intervals.length==1){
    return intervals
  }
  intervals.sort(function (x, y) {
    return x[0] - y[0]
  })
  let res = [],arr=[]
  let L=0,R=L+1
  while(R<intervals.length){
    if(intervals[L][1]>=intervals[R][0]){
      arr = [intervals[L][0], Math.max(intervals[L][1], intervals[R][1])]
      intervals.splice(L,R-L+1,arr)   
      L = intervals.indexOf(arr)
      R=L+1
      if(R>=intervals.length){
        res.push(arr)
      }
    }else{
      if(arr.toString()!=[].toString()){
        res.push(arr)
        arr=[]
      }else{
        res.push(intervals[L])
      }
      L=R
      if(L>=intervals.length-1){
        res.push(intervals[L])
      }
      R=L+1
    }
  }
  return res
};
2020.10.09

1.颜色分类

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var sortColors = function(nums) {
  let num0=0,num1=0,num2=0
  for(let i=0;i<nums.length;i++){
    if(nums[i]==0) num0++
    if(nums[i]==1) num1++
    if(nums[i]==2) num2++
  }
  nums.fill(0,0,num0)
  nums.fill(1,num0,num1+num0)
  nums.fill(2,num1+num0,num2+num1+num0)
  return nums
};

2.最大数

/**
 * @param {number[]} nums
 * @return {string}
 */
var largestNumber = function(nums) {
  nums.sort((a,b)=>{
    let s1=`${a}${b}`
    let s2=`${b}${a}`
    return s2-s1
  })
  return nums[0]?nums.join(''):'0'
};

3.存在重复元素Ⅲ

/**
 * @param {number[]} nums
 * @param {number} k
 * @param {number} t
 * @return {boolean}
 */
var containsNearbyAlmostDuplicate = function(nums, k, t) {
  for(let i=0;i<nums.length;i++){
    for(let j=i+1;j<k+i+1;j++){
      if(Math.abs(nums[i]-nums[j])<=t){
        return true
      }
    }
  }
  return false
};
  • 虽然我用JS提交以上代码没有超时,但是力扣解析中说这种方法会超时,所以我还写了以下的方法(桶排序)来进行解答.
10.10

1.H指数

/**
 * @param {number[]} citations
 * @return {number}
 */
var hIndex = function (citations) {
  citations.sort((a,b)=>b-a)
  let i=0
  while(i<citations.length&&citations[i]>i){
    i++
  }
  return i
};

2.用最少数量的箭引爆气球

/**
 * @param {number[][]} points
 * @return {number}
 */
var findMinArrowShots = function(points) {
  if(points.length==0) return 0
  points.sort((x,y)=>x[0]-y[0])
  let L=0
  let res=1
  while(L<points.length-1){
    if(points[L][1]>=points[L+1][0]){
      let arr = [Math.max(points[L][0],points[L+1][0]),Math.min(points[L][1],points[L+1][1])]
      points.splice(L,2,arr)
    }else{
      res++
      L++
    }
  }
  return res
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个比较复杂的算法,需要考虑多个因素,如班级数量、每个班级的课程数、每周可用的教室和时间段等等。以下是一个简单的 PHP 代码示例,可以作为一个思路参考: ```php // 定义班级和课程信息 $classes = array( 'class1' => array('course1', 'course2', 'course3'), 'class2' => array('course1', 'course4', 'course5'), 'class3' => array('course2', 'course3', 'course5') ); // 定义可用的教室和时间段 $rooms = array('room1', 'room2', 'room3'); $timeSlots = array('Monday 8:00-10:00', 'Monday 10:00-12:00', 'Tuesday 8:00-10:00', 'Tuesday 10:00-12:00', 'Wednesday 8:00-10:00', 'Wednesday 10:00-12:00', 'Thursday 8:00-10:00', 'Thursday 10:00-12:00', 'Friday 8:00-10:00', 'Friday 10:00-12:00'); // 定义排课结果 $schedule = array(); // 循环班级和课程 foreach ($classes as $class => $courses) { // 每个班级每门课程需要排几节课 $numCourses = count($courses); $numLessons = ceil($numCourses / count($timeSlots)); // 按时间段循环排课 $i = 0; foreach ($timeSlots as $timeSlot) { // 每个时间段随机选择一个可用的教室 $room = $rooms[array_rand($rooms)]; // 循环排课,直到排完所有课程 for ($j = 0; $j < $numLessons; $j++) { if ($i >= $numCourses) break; $schedule[] = array( 'class' => $class, 'course' => $courses[$i], 'room' => $room, 'time' => $timeSlot ); $i++; } } } // 输出排课结果 foreach ($schedule as $lesson) { echo $lesson['class'] . ' ' . $lesson['course'] . ' ' . $lesson['room'] . ' ' . $lesson['time'] . '<br>'; } ``` 这段代码仅仅是一个简单的示例,实际应用中需要根据具体情况对代码进行修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值